From ef4c0d31457a4eec6d078cae88bf567ef903f623 Mon Sep 17 00:00:00 2001 From: Ejiro Edwin Obamrevwo Date: Mon, 19 Aug 2019 19:50:47 +0100 Subject: [PATCH] Update Sendam using Sequelize (As ORM) and Mysql2 as Database --- .sequelizerc | 8 + Readme.md | 2 +- Server/app.js | 21 +- Server/config/config.js | 22 ++ Server/config/db.js | 33 +- Server/controllers/ParcelsController.js | 285 +++++++------- Server/controllers/UsersController.js | 249 ++++++------ Server/helpers/helper.js | 1 + Server/middleware/auth.js | 2 +- .../migrations/20190814202123-create-users.js | 48 +++ .../20190814202648-create-parcels.js | 62 +++ Server/models/index.js | 37 ++ Server/models/parcels.js | 20 + Server/models/users.js | 13 + Server/routes/users.js | 6 +- package-lock.json | 353 ++++++++++++++++++ package.json | 6 +- 17 files changed, 898 insertions(+), 270 deletions(-) create mode 100644 .sequelizerc create mode 100644 Server/config/config.js create mode 100644 Server/migrations/20190814202123-create-users.js create mode 100644 Server/migrations/20190814202648-create-parcels.js create mode 100644 Server/models/index.js create mode 100644 Server/models/parcels.js create mode 100644 Server/models/users.js diff --git a/.sequelizerc b/.sequelizerc new file mode 100644 index 0000000..3a58ef5 --- /dev/null +++ b/.sequelizerc @@ -0,0 +1,8 @@ +var path = require('path'); + +module.exports = { + 'config': path.resolve('./', 'server/config/config.js'), + 'migrations-path': path.resolve('./', 'server/migrations'), + 'seeders-path': path.resolve('./', 'server/seeders'), + 'models-path': path.resolve('./', 'server/models') +}; \ No newline at end of file diff --git a/Readme.md b/Readme.md index b5b5a77..f26ac38 100644 --- a/Readme.md +++ b/Readme.md @@ -1,4 +1,4 @@ -# Send-IT +# Send-AM SendAM is a courier service that helps users deliver parcels to different destinations. SendIT provides courier quotes based on weight categories. ## Feature diff --git a/Server/app.js b/Server/app.js index ae33acb..83cf595 100644 --- a/Server/app.js +++ b/Server/app.js @@ -3,28 +3,13 @@ const bodyParser = require('body-parser'); const path = require('path'); const cors = require('cors'); const mysql=require('mysql'); +const db = require('./config/db'); // const swagger = require("swagger-ui-express"); // import swaggerDocument from "../swagger.js"; let app = express(); -const db = mysql.createConnection ({ - host: 'localhost', - user: 'root', - password: '', - database: 'sendam' -}); - -// connect to database -db.connect((err) => { - if (err) { - throw err; - } - console.log('Connected to new database'); -}); -global.db = db; - const parcelRoute = require('./routes/parcels'); const userRoute = require('./routes/users'); @@ -32,7 +17,9 @@ const authRoute = require('./routes/auth'); app.set('views', path.join(__dirname, 'views')); -app.use(bodyParser.urlencoded({ extended: false })) +// app.use(bodyParser.urlencoded({ extended: false })) +app.use(bodyParser.json()); +app.use(bodyParser.urlencoded({ extended: true })); app.use( diff --git a/Server/config/config.js b/Server/config/config.js new file mode 100644 index 0000000..0cb88ba --- /dev/null +++ b/Server/config/config.js @@ -0,0 +1,22 @@ +module.exports = { + development: { + host: '127.0.0.1', + database: 'SendIt', + dialect: 'mysql', + username: 'root', + password: '', + port: 3306 + }, + production: { + url: process.env.DATABASE_URL, + dialect: 'mysql' + }, + staging: { + url: process.env.DATABASE_URL, + dialect: 'mysql' + }, + test: { + url: process.env.DATABASE_URL || '', + dialect: 'mysql' + } +}; \ No newline at end of file diff --git a/Server/config/db.js b/Server/config/db.js index 98996f5..965f0a3 100644 --- a/Server/config/db.js +++ b/Server/config/db.js @@ -1,18 +1,19 @@ -// const mysql=require('mysql'); +const Sequelize = require('sequelize') +const db = {} +const sequelize = new Sequelize('sendit', 'root', '', { + host: 'localhost', + dialect: 'mysql', + operatorsAliases: false, -// const connection=mysql.createConnection({ -// host:process.env.HOST, -// user:process.env.USER, -// password:'', -// database:process.env.DATABASE -// }); -// connection.connect(function(error){ -// if(!!error){ -// console.log(error); -// }else{ -// console.log('Database Connected!:)'); -// } -// }); -// global.connection = connection; + pool: { + max: 5, + min: 0, + acquire: 30000, + idle: 10000 + } +}) -// module.exports = connection; \ No newline at end of file +db.sequelize = sequelize +db.Sequelize = Sequelize + +module.exports = db \ No newline at end of file diff --git a/Server/controllers/ParcelsController.js b/Server/controllers/ParcelsController.js index 827f8de..597c8a3 100644 --- a/Server/controllers/ParcelsController.js +++ b/Server/controllers/ParcelsController.js @@ -1,7 +1,10 @@ const moment = require('moment'); // const db = require('../config/db'); const dotenv = require('dotenv'); -const Helper = require('../helpers/helper'); +const helper = require ('../helpers/helper'); +const Users = require('../models/users'); +const Parcels = require('../models/parcels'); + const { createParcelsSchema, destinationSchema, @@ -31,172 +34,204 @@ class Parcels { }; - const query = `INSERT INTO parcels (placedby,weight,weightmetric,senton,status,fromaddress,toaddress,currentlocation,itemname, recipient) - VALUES('${newOrder.placedBy}','${newOrder.weight}','${newOrder.weightmetric}','${newOrder.sentOn}','${newOrder.status}','${newOrder.fromAddress}' - ,'${newOrder.toAddress}','${newOrder.currentLocation}','${newOrder.itemName}','${newOrder.recipient}') returning *` - db.query(query) - .then((result) => { - if(result.rowCount === 0) { - return res.status(500).json({ "status": res.statusCode, "Message": 'An error occured while trying to save your order ensure that weight is a valid number and Address are not empty'}) - } else if(result.rowCount >= 1) { - return res.status(201).json({"status": res.statusCode, "message": "New parcel added successfuly", "data": result.rows[0]}); - } + Parcels.create(newOrder) + .then(result =>{ + res.status(200).send({'status':200, 'message': result.itemName + " added Successfully"}); }) - .catch((error) => { - res.status(500).json({ "status": res.statusCode, "error": `An error occured while trying to save your order ${error}`}) + .catch(err =>{ + res.status(500).send({'status':200,'error':`An error occured while trying to save your order ${err}`}) }) } static getAll(req, res) { if(!req.adminStatus) { - const query = `SELECT * FROM parcels where placedBy ='${req.user}'` - db.query(query) - .then((result) => { - if(result.rowCount === 0) { - return res.status(204).json({ "status": res.statusCode, "error": 'You have not created any parcels'}) - } else if (result.rowCount >= 1) { - res.status(200).json({"status": res.statusCode, "data": result.rows}); + Parcels.findAll({ + where:{ + placedBy: req.user } }) - .catch((error) => { - res.status(500).json({ "status": res.statusCode, "error": "Could not get parcels from database"}) - }) - - } else { - const query = `SELECT * FROM parcels` - db.query(query) - .then((result) => { - if(result.rowCount === 0) { - return res.status(204).json({ "status": res.statusCode, "error": 'No Parcels'}) - } else if (result.rowCount >= 1) { - res.status(200).json({"status": res.statusCode, "data": result.rows}); - } - }) - .catch((error) => { - res.status(500).json({ "status": res.statusCode, "error": "Could not get parcels from database"}) - }) + .then(result =>{ + if(!result){ + res.status(204).send({"status": 204, "message": "User has no parcel delivery orders"}) + } + else{ + res.status(200).send({"status": 200, "data": result}) + } + }) + .catch(err => { + res.send('error: '+ err); + }) + }else{ + Parcels.findAll({raw:true}) + .then(result =>{ + if(!result){ + res.status(204).send({"status": 204, "message": "No Parcels"}) } + else{ + res.status(200).send({"status": 200, "data": result}) + } + }) + .catch(err => { + res.send('error: '+ err); + }) } + } + static getOne(req, res) { - let id = req.params.id if (!req.adminStatus) { - const query = `SELECT * FROM parcels WHERE ID='${id}'and placedBy='${req.user}'` - db.query(query) - .then((result) => { - if(result.rowCount === 0) { - return res.status(400).json({ "status": res.statusCode, "error": 'You do not own such parcel delivery order'}) - } else if (result.rowCount >= 1) { - res.status(200).json({"status": res.statusCode, "data": result.rows[0]}); - } - }) - .catch((error) => { - res.status(500).json({ "status": res.statusCode, "error": "Could not get parcels from database"}) - }) - - } else { - const query = `SELECT * FROM parcels WHERE ID='${id}'` - db.query(query) - .then((result) => { - if(result.rowCount === 0) { - return res.status(204).json({ "status": res.statusCode, "error": 'No such parcel'}) - } else if (result.rowCount >= 1) { - res.status(200).json({"status": res.statusCode, "data": result.rows[0]}); - } - }) - .catch((error) => { - res.status(500).json({ "status": res.statusCode, "error": "Could not get parcels from database"}) - }) + + Parcels.findOne({ + where:{ + ID:req.params.id, + placedBy: req.user + } + }) + .then(result =>{ + if(!result){ + res.status(204).send({"status": 204, "message": "You do not own such parcel delivery order"}) + } + else{ + res.status(200).send({"status": 200, "data": result}) + } + }) + .catch(err => { + res.send('error: '+ err); + }) + }else{ + Parcels.findAll({ + where:{ + id:req.params.id, + } + }) + .then(result =>{ + if(!result){ + res.status(204).send({"status": 204, "message": "No such parcel"}); + } + else{ + res.status(200).send({"status": 200, "data": result}) } - } + }) + .catch(err => { + res.send('error: '+ err); + }) + } +} + static cancel(req, res) { - const id = req.params.id; const newStatus = 'canceled'; - const query = `UPDATE parcels SET status='${newStatus}' WHERE id='${id}' and placedby='${req.user}' returning *` - db.query(query) - .then((result) => { - if(result.rowCount === 0) { - return res.status(400).json({ "status": 400, "error": 'Only parcel owners can cancel their delivery order'}) - } else if (result.rowCount >= 1) { - return res.status(200).json({"status": 200, "message": "Your parcel delivery order has been cancelled ", "data": result.rows[0] }); - } - }) - .catch((error) => { - return res.status(500).json({ "status": 500, "error": "Could not get parcels from database"}) - }) + Parcels.update( + {status:newStatus}, + {where : { + id = req.params.id, + placedBy: req.user + }} + ) + .then(result => { + if(!result){ + res.status(400).send({ "status": 400, "message": 'Only parcel owners can cancel their delivery order'}) + } + else{ + res.status(200).send({"status": 200, "Message": "Your parcel delivery order has been cancelled ", 'data':result}); + } + }) + .catch(err => { + res.send('error: '+ err); + }) + } + static changeDestination(req, res) { - const id = req.params.id; + const fieldError = destinationSchema(req.body) - if(fieldError) { - return res.status(400).json({ "status": 400, "error": fieldError}) - } + if (fieldError.error) return res.status(400).send(fieldError.error.details[0].message); + const newDestination = req.body.toAddress - const query = `UPDATE parcels SET toAddress='${newDestination}' WHERE id='${id}' AND placedby='${req.user}' returning *` - db.query(query) - .then((result) => { - if(result.rowCount === 0) { - return res.status(204).json({ "status": 204, "error": 'Only parcel owners can change order destination'}) - } else if (result.rowCount >= 1) { - return res.status(200).json({"status": 200, "Message": "The destination has been changed successfully ", "data": result.rows[0]}); + + Parcels.update( + {toAddress:newDestination}, + {where : { + id = req.params.id, + placedBy: req.user + }} + ) + .then(result => { + if(!result){ + res.status(204).json({ "status": 204, "message": 'Only parcel owners can change order destination'}) + } + else{ + res.status(200).send({"status": 200, "Message": "The destination has been changed successfully ", 'data':result}); } }) - .catch((error) => { - return res.status(500).json({ "status": 500, "error": "An error ocurred while trying to change the parcel Destination"}) + .catch(err => { + res.send('error: '+ err); }) + } + + static changeCurrentLocation(req, res) { if (req.adminStatus) { - const id = req.params.id; const fieldError = currentLocationSchema(req.body) - if(fieldError) { - return res.status(400).json({ "status": 400, "error": fieldError}) - - } + if (fieldError.error) return res.status(400).send(fieldError.error.details[0].message); + const currentLocation = req.body.currentLocation - const query = `UPDATE parcels SET toaddress='${currentLocation}' WHERE id='${id}' returning *` - db.query(query) - .then((result) => { - if(result.rowCount === 0) { - return res.status(204).json({ "status": 204, "error": 'No such parcel'}) - } else if (result.rowCount >= 1) { - res.status(200).json({"status": 200, "Message": "The current location of the order has been updated successfully ", "data": result.rows[0] }); + + Parcels.update( + {toAddress:currentLocation}, + {where : { + id = req.params.id + }} + ) + .then(result => { + if(!result){ + res.status(204).json({ "status": 204, "message": 'No such parcel'}) } - }) - .catch((error) => { - res.status(500).json({ "status": 500, "error": "Could not find the parcel in database"}) - }) + else{ + res.status(200).send({"status": 200, "Message": "The current location of the order has been updated successfully", 'data':result}); + } + }) + .catch(err => { + res.send('error: '+ err); + }) + } else { - res.json({"Message": "Only Admins can access this route"}) + res.send({"Message": "Only Admins can access this route"}) } } + + static changeStatus(req, res) { if (req.adminStatus) { - const id = req.params.id; const fieldError = changeStatusSchema(req.body) - if(fieldError) { - return res.status(400).json({ "status": res.statusCode, "error": fieldError}) - } + if (fieldError.error) return res.status(400).send(fieldError.error.details[0].message); + const status = req.body.status - const query = `UPDATE parcels SET status='${status}' WHERE id='${id}' AND status='pending'` - db.query(query) - .then((result) => { - if(result.rowCount === 0) { - return res.status(400).json({ "status": 400, "error": 'This parcel delivery order might have been cancelled or delivered'}) - } else if (result.rowCount >= 1) { - Helper.sendEmail() - res.status(200).json({"status": 200, "Message": "The status of the parcel has been changed successfully "}); - } - }) - .catch((error) => { - res.status(500).json({ "status": 500, "error": "Could not find the parcel in database"}) - }) + Parcels.update( + {status:status}, + {where : { + id = req.params.id, + status: 'pending' + }} + ) + .then(result => { + if(!result){ + res.status(204).json({ "status": 204, "message": 'This parcel delivery order might have been cancelled or delivered'}) + } + else{ + helper.sendEmail() + res.status(200).send({"status": 200, "Message": "The status of the parcel has been changed successfully", 'data':result}); + } + }) + .catch(err => { + res.send('error: '+ err); + }) } else { res.json({"Message": "Only Admins can access this route"}) } diff --git a/Server/controllers/UsersController.js b/Server/controllers/UsersController.js index 0a8d032..d25e482 100644 --- a/Server/controllers/UsersController.js +++ b/Server/controllers/UsersController.js @@ -2,6 +2,10 @@ const moment = require ('moment'); // const db = require('../config/db'); const dotenv = require('dotenv'); const helper = require ('../helpers/helper'); +const Users = require('../models/users'); +const Parcels = require('../models/parcels'); + + const { signUpSchema, loginSchema @@ -10,13 +14,14 @@ const { dotenv.config(); class User { - static signup(req, res) { + static signup(req, res) { const fieldError = signUpSchema(req.body) if (fieldError.error) return res.status(400).send(fieldError.error.details[0].message); const hashedPassword = helper.hashPassword(req.body.password); - const newUser = { + + const UserData = { firstname: req.body.firstname, lastname: req.body.lastname, othernames: req.body.othernames, @@ -26,150 +31,184 @@ class User { isAdmin: 'false', password: hashedPassword }; - - - const Check = `SELECT * FROM users WHERE email='${newUser.email}'` - db.query(Check, function (err, result) { - if (err) return res.status(500).send(err); - - if (result.length > 0) res.send({"error": "Username already exists"}) - - }); - const query = `INSERT INTO users (firstname,lastname,othernames,email,username,registered,isAdmin,password) - VALUES('${newUser.firstname}','${newUser.lastname}','${newUser.othernames}','${newUser.email}','${newUser.username}', - '${newUser.registered}','${newUser.isAdmin}','${newUser.password}')` - - db.query(query, function (error, result) { - if (error) return res.status(500).send(error); + Users.findOne({ + where:{ + email:req.body.email + } + }).then(user =>{ + if(!user){ + Users.create(UserData) + .then(user =>{ + res.status(200).send({status: user.email + " Registered Successfully"}); + }) + .catch(err =>{ + res.send('error:'+err) + }) + + }else{ + res.status(400).send({error:"User already exists"}); + } - if(result.rowCount >=1) { - res.status(200).json({"status":200,"message":"User saved successfully","data": result.rows[0]}) - } else if (result.rowCount === 0) { - res.status(500).json({"status": 500, "message": "The user could not be saved"}) - } + }) + .catch(err => { + res.send('error: '+ err); + }) - - }); } - + static login (req, res) { - - const fieldError = loginSchema(req.body) + + const fieldError = loginSchema(req.body) if (fieldError.error) return res.status(400).send(fieldError.error.details[0].message); - - + + const loginData = { email: req.body.email, - password: req.body.password, - } + password: req.body.password + }; - const query = `SELECT * FROM users WHERE email='${loginData.email}'` - db.query(query, function (err, result) { - if (err) return res.status(500).send(err); - - if(result.rowCount ==0) { - res.status(400).json({ "status": 400, "error": 'An error occured while trying to log you in Check your details again'}) - } else if (result.rowCount >=1) { - if(!helper.comparePassword(result.rows[0].password, req.body.password)) { - return res.status(400).json({ 'message': 'The credentials you provided are incorrect' }); - } else { - loginData.userId=result.rows[0].id - loginData.isAdmin=result.rows[0].isadmin - loginData.username=result.rows[0].firstname - delete(loginData.password) - const token = helper.generateToken(loginData); - return res.status(200).json({ "token": token, "message": "Login successful" }); - } + Users.findOne({ + where:{ + email: req.body.email + } + }).then(user =>{ + if(user){ + // if(!helper.comparePassword(result.rows[0].password, req.body.password)) { + if(!helper.comparePassword(user.password, req.body.password)) { + return res.status(400).json({ 'message': 'The credentials you provided are incorrect' }); + } + else{ + loginData.userId=user.id + loginData.isAdmin=user.isadmin + loginData.username=user.username + delete(loginData.password) + const token = helper.generateToken(loginData); + return res.status(200).json({ "token": token, "message": "Login successful" }); + } + } + else{ + res.status(400).send("User does not exist"); } }) -} + .catch(err => { + res.send('error: '+ err); + }) + } static getAll (req, res) { - const query = 'SELECT * FROM users' if(req.adminStatus){ - db.query(query) - .then((result) => { - if (result.rowCount ===0) { - res.status(204).json({"status": 204, "message": "No Users Found"}) - } else if (result.rowCount >=1 ) { - res.json({"status": 200, "data": result.rows}) - } - }) - .catch((error) => { - res.status(500).json({"status": 500, "message":"An error occurd when trying to get users from database"}) - }) - } else { - res.status(403).json({"Message": "Only Admins can access this route"}) + Users.findAll({raw:true}).then(AllUser =>{ + if(!AllUser){ + res.status(204).send({"status": 204, "message": "No Users Found"}) + } + else{ + res.status(200).send({"status": 200, "data": AllUser}) + } + }) + .catch(err => { + res.send('error: '+ err); + }) + } + else{ + res.status(403).send({"Message": "Only Admins can access this route"}) } - } + +} + static getOne (req, res) { - let id = req.params.id if(req.adminStatus) { - const query = `SELECT * FROM users WHERE ID='${id}'` - db.query(query) - .then((result) => { - if (result.rowCount ===0) { - res.status(204).json({"status": 204, "message": "No Such User Found"}) - } else if (result.rowCount >=1 ) { - res.json({"status": 200, "data": result.rows}) + Users.findOne({ + where:{ + id: req.params.id } }) - .catch((error) => { - res.status(500).json({"status": 500, "message":"An error occurd when trying to get user from database"}) - }) - } else { - res.status(403).json({"status": 403, "message":"This is an admin functionality"}) + + .then(user =>{ + if(!user){ + res.status(204).send({"status": 204, "message": "No Such User Found"}) + } + else{ + res.status(200).send({"status": 200, "data": user}) + } + }) + .catch(err => { + res.send('error: '+ err); + }) } - } + else{ + res.status(403).send({"Message": "Only Admins can access this route"}) + } + +} static getUserParcels (req, res) { - const id = req.params.id + if(req.adminStatus) { - const query = `SELECT * FROM parcels WHERE placedBy='${id}'` - db.query(query) - .then((result) => { - if (result.rowCount ===0) { - res.status(400).json({"status": 400, "message": "User has no parcel delivery orders"}) - } else if (result.rowCount >=1 ) { - res.status(200).json({"status": 200, "data": result.rows}) + Parcels.findAll({ + where:{ + placedBy: req.params.id } }) - .catch((error) => { - res.status(500).json({"status": 500, "message":"An error occurd when trying to get user parcels from database"}) - }) - } else { - res.status(403).json({"Message": "Only Admins can access this route"}) + + .then(result =>{ + if(!result){ + res.status(400).send({"status": 400, "message": "User has no parcel delivery orders"}) + } + else{ + res.status(200).send({"status": 200, "data": result}) + } + }) + .catch(err => { + res.send('error: '+ err); + }) } - } + else{ + res.status(403).send({"Message": "Only Admins can access this route"}) + } + +} + + + static makeAdmin(req, res) { if (req.adminStatus) { - const id = req.params.id; const adminstatus = true - const query = `UPDATE users SET isadmin='${adminstatus}' WHERE id='${id}' RETURNING *` - db.query(query) - .then((result) => { - if(result.rowCount === 0) { - return res.status(204).json({ "status": 204, "error": 'No such User'}) - } else if (result.rowCount >= 1) { - res.status(200).json({"status": 200, "Message": "The user has been made an Admin successfully "}); + Users.update( + {isadmin:true}, + {where : { + id = req.params.id + }} + ) + .then(result => { + if(!result){ + res.status(204).send({ "status": 204, "message": 'No such User'}) + } + else{ + res.status(200).send({"status": 200, "Message": "The user has been made an Admin successfully "}); } }) - .catch((error) => { - res.status(500).json({ "status": 500, "error": "An error occured while trying to make user an Admmin, try again"}) + .catch(err => { + res.send('error: '+ err); }) - } else { - res.status(403).json({"Message": "Only Admins can access this route"}) - } + } + else{ + res.status(403).send({"Message": "Only Admins can access this route"}) + } + } + } + + + module.exports = User; \ No newline at end of file diff --git a/Server/helpers/helper.js b/Server/helpers/helper.js index c04ffb2..540bf1b 100644 --- a/Server/helpers/helper.js +++ b/Server/helpers/helper.js @@ -24,6 +24,7 @@ const helper = { generateToken(payload) { + process.env.SECRET="secret"; const token = jwt.sign( payload, process.env.SECRET, { expiresIn: '20d' } diff --git a/Server/middleware/auth.js b/Server/middleware/auth.js index 27ce6c8..0f542b0 100644 --- a/Server/middleware/auth.js +++ b/Server/middleware/auth.js @@ -11,7 +11,7 @@ class Auth { const bearerToken = bearerArray[1]; req.token = bearerToken; - jwt.verify(req.token, process.env.SECRET, (err, data) => { + jwt.verify(req.token, "SECRET", (err, data) => { if (err) { res.status(403).send("You cannot access this page because you require a token to access it"); } else { diff --git a/Server/migrations/20190814202123-create-users.js b/Server/migrations/20190814202123-create-users.js new file mode 100644 index 0000000..230522a --- /dev/null +++ b/Server/migrations/20190814202123-create-users.js @@ -0,0 +1,48 @@ +'use strict'; +module.exports = { + up: (queryInterface, Sequelize) => { + return queryInterface.createTable('Users', { + id: { + allowNull: false, + autoIncrement: true, + primaryKey: true, + type: Sequelize.INTEGER + }, + email: { + type: Sequelize.STRING + }, + firstName: { + type: Sequelize.STRING + }, + lastName: { + type: Sequelize.STRING + }, + othernames: { + type: Sequelize.STRING + }, + username: { + type: Sequelize.STRING + }, + registered: { + type: Sequelize.DATE + }, + isAdmin: { + type: Sequelize.INTEGER + }, + password: { + type: Sequelize.STRING + }, + createdAt: { + allowNull: false, + type: Sequelize.DATE + }, + updatedAt: { + allowNull: false, + type: Sequelize.DATE + } + }); + }, + down: (queryInterface, Sequelize) => { + return queryInterface.dropTable('Users'); + } +}; \ No newline at end of file diff --git a/Server/migrations/20190814202648-create-parcels.js b/Server/migrations/20190814202648-create-parcels.js new file mode 100644 index 0000000..f24deb4 --- /dev/null +++ b/Server/migrations/20190814202648-create-parcels.js @@ -0,0 +1,62 @@ +'use strict'; +module.exports = { + up: (queryInterface, Sequelize) => { + return queryInterface.createTable('parcels', { + id: { + allowNull: false, + autoIncrement: true, + primaryKey: true, + type: Sequelize.INTEGER + }, + placedBy: { + type: Sequelize.INTEGER, + allowNull: false, + references: { + model: 'Users', + key: 'id' + } + }, + weight: { + type: Sequelize.DOUBLE + }, + weightmetric: { + type: Sequelize.STRING + }, + sentOn: { + type: Sequelize.DATE + }, + deliveredOn: { + type: Sequelize.INTEGER + }, + status: { + type: Sequelize.STRING + }, + fromAddress: { + type: Sequelize.STRING + }, + toAddress: { + type: Sequelize.STRING + }, + currentLocation: { + type: Sequelize.STRING + }, + itemname: { + type: Sequelize.STRING + }, + recipient: { + type: Sequelize.STRING + }, + createdAt: { + allowNull: false, + type: Sequelize.DATE + }, + updatedAt: { + allowNull: false, + type: Sequelize.DATE + } + }); + }, + down: (queryInterface, Sequelize) => { + return queryInterface.dropTable('parcels'); + } +}; \ No newline at end of file diff --git a/Server/models/index.js b/Server/models/index.js new file mode 100644 index 0000000..c7cc49e --- /dev/null +++ b/Server/models/index.js @@ -0,0 +1,37 @@ +'use strict'; + +const fs = require('fs'); +const path = require('path'); +const Sequelize = require('sequelize'); +const basename = path.basename(__filename); +const env = process.env.NODE_ENV || 'development'; +const config = require(__dirname + '/../config/config.js')[env]; +const db = {}; + +let sequelize; +if (config.use_env_variable) { + sequelize = new Sequelize(process.env[config.use_env_variable], config); +} else { + sequelize = new Sequelize(config.database, config.username, config.password, config); +} + +fs + .readdirSync(__dirname) + .filter(file => { + return (file.indexOf('.') !== 0) && (file !== basename) && (file.slice(-3) === '.js'); + }) + .forEach(file => { + const model = sequelize['import'](path.join(__dirname, file)); + db[model.name] = model; + }); + +Object.keys(db).forEach(modelName => { + if (db[modelName].associate) { + db[modelName].associate(db); + } +}); + +db.sequelize = sequelize; +db.Sequelize = Sequelize; + +module.exports = db; diff --git a/Server/models/parcels.js b/Server/models/parcels.js new file mode 100644 index 0000000..663de25 --- /dev/null +++ b/Server/models/parcels.js @@ -0,0 +1,20 @@ +'use strict'; +module.exports = (sequelize, DataTypes) => { + const parcels = sequelize.define('parcels', { + placedBy: DataTypes.INTEGER, + weight: DataTypes.DOUBLE, + weightmetric: DataTypes.STRING, + sentOn: DataTypes.DATE, + deliveredOn: DataTypes.INTEGER, + status: DataTypes.STRING, + fromAddress: DataTypes.STRING, + toAddress: DataTypes.STRING, + currentLocation: DataTypes.STRING, + itemname: DataTypes.STRING, + recipient: DataTypes.STRING + }, {}); + parcels.associate = function(models) { + parcels.belongsTo(models.Users, {}) + }; + return parcels; +}; \ No newline at end of file diff --git a/Server/models/users.js b/Server/models/users.js new file mode 100644 index 0000000..b4ee339 --- /dev/null +++ b/Server/models/users.js @@ -0,0 +1,13 @@ +const Sequelize = require('sequelize') +const db = require('../config/db.js') + +module.exports = db.sequelize.define('user', { + email: Sequelize.STRING, + firstname: Sequelize.STRING, + lastname: Sequelize.STRING, + othernames: Sequelize.STRING, + username: Sequelize.STRING, + registered: Sequelize.DATE, + isAdmin: Sequelize.INTEGER, + password: Sequelize.STRING + }, {}); diff --git a/Server/routes/users.js b/Server/routes/users.js index 7fc12fc..97f1ee7 100644 --- a/Server/routes/users.js +++ b/Server/routes/users.js @@ -7,8 +7,8 @@ let router = express.Router(); router.use(express.json()); router.get('/', Auth.verifyToken,UsersFromDatabase.getAll); -router.get('/:id',Auth.verifyToken,UsersFromDatabase.getOne); -router.get('/:id/parcels',Auth.verifyToken,UsersFromDatabase.getUserParcels); -router.post('/:id/makeadmin',Auth.verifyToken,UsersFromDatabase.makeAdmin); +// router.get('/:id',Auth.verifyToken,UsersFromDatabase.getOne); +// router.get('/:id/parcels',Auth.verifyToken,UsersFromDatabase.getUserParcels); +// router.post('/:id/makeadmin',Auth.verifyToken,UsersFromDatabase.makeAdmin); module.exports = router; \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 05146ef..375149a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -975,6 +975,11 @@ "resolved": "https://registry.npmjs.org/@types/cookiejar/-/cookiejar-2.1.1.tgz", "integrity": "sha512-aRnpPa7ysx3aNW60hTiCtLHlQaIFsXFCgQlpakNgDNVFzbtusSY8PwjAQgRWfSk0ekNoBjO51eQRB6upA9uuyw==" }, + "@types/geojson": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-1.0.6.tgz", + "integrity": "sha512-Xqg/lIZMrUd0VRmSRbCAewtwGZiAk3mEUDvV4op1tGl+LvyPcb/MIOSxTl9z+9+J+R4/vpjiCAT4xeKzH9ji1w==" + }, "@types/node": { "version": "12.7.1", "resolved": "https://registry.npmjs.org/@types/node/-/node-12.7.1.tgz", @@ -1453,6 +1458,11 @@ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true }, + "camelize": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.0.tgz", + "integrity": "sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs=" + }, "caniuse-lite": { "version": "1.0.30000989", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000989.tgz", @@ -1578,6 +1588,15 @@ "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", "dev": true }, + "cls-bluebird": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cls-bluebird/-/cls-bluebird-2.1.0.tgz", + "integrity": "sha1-N+8eCAqP+1XC9BZPU28ZGeeWiu4=", + "requires": { + "is-bluebird": "^1.0.2", + "shimmer": "^1.1.0" + } + }, "collection-visit": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", @@ -1637,6 +1656,11 @@ "safe-buffer": "5.1.2" } }, + "content-security-policy-builder": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/content-security-policy-builder/-/content-security-policy-builder-2.1.0.tgz", + "integrity": "sha512-/MtLWhJVvJNkA9dVLAp6fg9LxD2gfI6R2Fi1hPmfjYXSahJJzcfvoeDOxSyp4NvxMuwWv3WMssE9o31DoULHrQ==" + }, "content-type": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", @@ -1749,6 +1773,11 @@ "assert-plus": "^1.0.0" } }, + "dasherize": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dasherize/-/dasherize-2.0.0.tgz", + "integrity": "sha1-bYCcnNDPe7iVLYD8hPoT1H3bEwg=" + }, "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -1835,6 +1864,11 @@ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" }, + "denque": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/denque/-/denque-1.4.1.tgz", + "integrity": "sha512-OfzPuSZKGcgr96rf1oODnfjqBFmr1DVoc/TrItj3Ohe0Ah1C5WX5Baquw/9U9KovnQ88EqmJbD66rKYUQYN1tQ==" + }, "depd": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", @@ -1850,6 +1884,11 @@ "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==" }, + "dns-prefetch-control": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/dns-prefetch-control/-/dns-prefetch-control-0.2.0.tgz", + "integrity": "sha512-hvSnros73+qyZXhHFjx2CMLwoj3Fe7eR9EJsFsqmcI1bB2OBWL/+0YzaEaKssCHnj/6crawNnUyw74Gm2EKe+Q==" + }, "doctrine": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", @@ -1859,11 +1898,21 @@ "esutils": "^2.0.2" } }, + "dont-sniff-mimetype": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/dont-sniff-mimetype/-/dont-sniff-mimetype-1.1.0.tgz", + "integrity": "sha512-ZjI4zqTaxveH2/tTlzS1wFp+7ncxNZaIEWYg3lzZRHkKf5zPT/MnEG6WL0BhHMJUabkh8GeU5NL5j+rEUCb7Ug==" + }, "dotenv": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-6.2.0.tgz", "integrity": "sha512-HygQCKUBSFl8wKQZBSemMywRWcEDNidvNbjGVyZu3nbZ8qq9ubiPoGLMdRDpfSrpkkm9BXYFkpKxxFX38o/76w==" }, + "dottie": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/dottie/-/dottie-2.0.1.tgz", + "integrity": "sha512-ch5OQgvGDK2u8pSZeSYAQaV/lczImd7pMJ7BcEPXmnFVjy4yJIzP6CsODJUTH8mg1tyH1Z2abOiuJO3DjZ/GBw==" + }, "ecc-jsbn": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", @@ -2171,6 +2220,11 @@ } } }, + "expect-ct": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/expect-ct/-/expect-ct-0.2.0.tgz", + "integrity": "sha512-6SK3MG/Bbhm8MsgyJAylg+ucIOU71/FzyFalcfu5nY19dH8y/z0tBJU0wrNBXD4B27EoQtqPF/9wqH0iYAd04g==" + }, "express": { "version": "4.17.1", "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", @@ -2337,6 +2391,11 @@ "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" }, + "feature-policy": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/feature-policy/-/feature-policy-0.3.0.tgz", + "integrity": "sha512-ZtijOTFN7TzCujt1fnNhfWPFPSHeZkesff9AXZj+UEjYBynWNUIYpC87Ve4wHzyexQsImicLu7WsC2LHq7/xrQ==" + }, "figures": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", @@ -2467,6 +2526,11 @@ "map-cache": "^0.2.2" } }, + "frameguard": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/frameguard/-/frameguard-3.1.0.tgz", + "integrity": "sha512-TxgSKM+7LTA6sidjOiSZK9wxY0ffMPY3Wta//MqwmX0nZuEHc8QrkV8Fh3ZhMJeiH+Uyh/tcaarImRy8u77O7g==" + }, "fresh": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", @@ -2974,6 +3038,19 @@ "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", "dev": true }, + "generate-function": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.3.1.tgz", + "integrity": "sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==", + "requires": { + "is-property": "^1.0.2" + } + }, + "generic-pool": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/generic-pool/-/generic-pool-3.7.1.tgz", + "integrity": "sha512-ug6DAZoNgWm6q5KhPFA+hzXfBLFQu5sTXxPpv44DmE0A2g+CiHoq9LTVdkXpZMkYVMoGw83F6W+WT0h0MFMK/w==" + }, "get-func-name": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", @@ -3129,6 +3206,56 @@ "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=" }, + "helmet": { + "version": "3.20.0", + "resolved": "https://registry.npmjs.org/helmet/-/helmet-3.20.0.tgz", + "integrity": "sha512-Ob+TqmQFZ5f7WgP8kBbAzNPsbf6p1lOj5r+327/ymw/IILWih3wcx9u/u/S8Mwv5wbBkO7Li6x5s23t3COhUKw==", + "requires": { + "depd": "2.0.0", + "dns-prefetch-control": "0.2.0", + "dont-sniff-mimetype": "1.1.0", + "expect-ct": "0.2.0", + "feature-policy": "0.3.0", + "frameguard": "3.1.0", + "helmet-crossdomain": "0.4.0", + "helmet-csp": "2.8.0", + "hide-powered-by": "1.1.0", + "hpkp": "2.0.0", + "hsts": "2.2.0", + "ienoopen": "1.1.0", + "nocache": "2.1.0", + "referrer-policy": "1.2.0", + "x-xss-protection": "1.2.0" + }, + "dependencies": { + "depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" + } + } + }, + "helmet-crossdomain": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/helmet-crossdomain/-/helmet-crossdomain-0.4.0.tgz", + "integrity": "sha512-AB4DTykRw3HCOxovD1nPR16hllrVImeFp5VBV9/twj66lJ2nU75DP8FPL0/Jp4jj79JhTfG+pFI2MD02kWJ+fA==" + }, + "helmet-csp": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/helmet-csp/-/helmet-csp-2.8.0.tgz", + "integrity": "sha512-MlCPeM0Sm3pS9RACRihx70VeTHmkQwa7sum9EK1tfw1VZyvFU0dBWym9nHh3CRkTRNlyNm/WFCMvuh9zXkOjNw==", + "requires": { + "camelize": "1.0.0", + "content-security-policy-builder": "2.1.0", + "dasherize": "2.0.0", + "platform": "1.3.5" + } + }, + "hide-powered-by": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/hide-powered-by/-/hide-powered-by-1.1.0.tgz", + "integrity": "sha512-Io1zA2yOA1YJslkr+AJlWSf2yWFkKjvkcL9Ni1XSUqnGLr/qRQe2UI3Cn/J9MsJht7yEVCe0SscY1HgVMujbgg==" + }, "hoek": { "version": "6.1.3", "resolved": "https://registry.npmjs.org/hoek/-/hoek-6.1.3.tgz", @@ -3150,6 +3277,26 @@ "lru-cache": "^5.1.1" } }, + "hpkp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/hpkp/-/hpkp-2.0.0.tgz", + "integrity": "sha1-EOFCJk52IVpdMMROxD3mTe5tFnI=" + }, + "hsts": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/hsts/-/hsts-2.2.0.tgz", + "integrity": "sha512-ToaTnQ2TbJkochoVcdXYm4HOCliNozlviNsg+X2XQLQvZNI/kCHR9rZxVYpJB3UPcHz80PgxRyWQ7PdU1r+VBQ==", + "requires": { + "depd": "2.0.0" + }, + "dependencies": { + "depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" + } + } + }, "http-errors": { "version": "1.7.2", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", @@ -3187,6 +3334,11 @@ "safer-buffer": ">= 2.1.2 < 3" } }, + "ienoopen": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/ienoopen/-/ienoopen-1.1.0.tgz", + "integrity": "sha512-MFs36e/ca6ohEKtinTJ5VvAJ6oDRAYFdYXweUnGY9L9vcoqFOU4n2ZhmJ0C4z/cwGZ3YIQRSB3XZ1+ghZkY5NQ==" + }, "ignore": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", @@ -3209,6 +3361,11 @@ "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", "dev": true }, + "inflection": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/inflection/-/inflection-1.12.0.tgz", + "integrity": "sha1-ogCTVlbW9fa8TcdQLhrstwMihBY=" + }, "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -3314,6 +3471,11 @@ "binary-extensions": "^1.0.0" } }, + "is-bluebird": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-bluebird/-/is-bluebird-1.0.2.tgz", + "integrity": "sha1-CWQ5Bg9KpBGr7hkUOoTWpVNG1uI=" + }, "is-buffer": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", @@ -3444,6 +3606,11 @@ "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", "dev": true }, + "is-property": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", + "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=" + }, "is-regex": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", @@ -3893,6 +4060,11 @@ "resolved": "https://registry.npmjs.org/log-driver/-/log-driver-1.2.7.tgz", "integrity": "sha512-U7KCmLdqsGHBLeWqYlFA0V0Sl6P08EE1ZrmA9cxjUE0WVqT9qnyVDPz1kzpFEP0jdJuFnasWIfSd7fsaNXkpbg==" }, + "long": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", + "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" + }, "loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -4122,6 +4294,14 @@ "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz", "integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==" }, + "moment-timezone": { + "version": "0.5.26", + "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.26.tgz", + "integrity": "sha512-sFP4cgEKTCymBBKgoxZjYzlSovC20Y6J7y3nanDc5RoBIXKlZhoYwBoZGe3flwU6A372AcRwScH8KiwV6zjy1g==", + "requires": { + "moment": ">= 2.9.0" + } + }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", @@ -4144,6 +4324,61 @@ "sqlstring": "2.3.1" } }, + "mysql2": { + "version": "1.6.5", + "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-1.6.5.tgz", + "integrity": "sha512-zedaOOyb3msuuZcJJnxIX/EGOpmljDG7B+UevRH5lqcv+yhy9eCwkArBz8/AO+/rlY3/oCsOdG8R5oD6k0hNfg==", + "requires": { + "denque": "^1.4.0", + "generate-function": "^2.3.1", + "iconv-lite": "^0.4.24", + "long": "^4.0.0", + "lru-cache": "^4.1.3", + "named-placeholders": "^1.1.2", + "seq-queue": "^0.0.5", + "sqlstring": "^2.3.1" + }, + "dependencies": { + "lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" + } + } + }, + "named-placeholders": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/named-placeholders/-/named-placeholders-1.1.2.tgz", + "integrity": "sha512-wiFWqxoLL3PGVReSZpjLVxyJ1bRqe+KKJVbr4hGs1KWfTZTQyezHFBbuKj9hsizHyGV2ne7EMjHdxEGAybD5SA==", + "requires": { + "lru-cache": "^4.1.3" + }, + "dependencies": { + "lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" + } + } + }, "nan": { "version": "2.14.0", "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", @@ -4191,6 +4426,11 @@ "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", "dev": true }, + "nocache": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/nocache/-/nocache-2.1.0.tgz", + "integrity": "sha512-0L9FvHG3nfnnmaEQPjT9xhfN4ISk0A8/2j4M37Np4mcDesJjHgEUfgPhdCyZuFI954tjokaIj/A3NdpFNdEh4Q==" + }, "node-environment-flags": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.6.tgz", @@ -5434,6 +5674,11 @@ "find-up": "^3.0.0" } }, + "platform": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/platform/-/platform-1.3.5.tgz", + "integrity": "sha512-TuvHS8AOIZNAlE77WUDiR4rySV/VMptyMfcfeoMgs4P8apaZM3JrnbzBiixKUv+XR6i+BXrQh8WAnjaSPFO65Q==" + }, "posix-character-classes": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", @@ -5471,6 +5716,11 @@ "ipaddr.js": "1.9.0" } }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" + }, "psl": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.3.0.tgz", @@ -5546,6 +5796,11 @@ "readable-stream": "^2.0.2" } }, + "referrer-policy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/referrer-policy/-/referrer-policy-1.2.0.tgz", + "integrity": "sha512-LgQJIuS6nAy1Jd88DCQRemyE3mS+ispwlqMk3b0yjZ257fI1v9c+/p6SD5gP5FGyXUIgrNOAfmyioHwZtYv2VA==" + }, "regenerate": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz", @@ -5740,6 +5995,15 @@ "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", "optional": true }, + "retry-as-promised": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/retry-as-promised/-/retry-as-promised-2.3.2.tgz", + "integrity": "sha1-zZdO5P2bX+A8vzGHHuSCIcB3N7c=", + "requires": { + "bluebird": "^3.4.6", + "debug": "^2.6.9" + } + }, "rimraf": { "version": "2.6.3", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", @@ -5818,6 +6082,50 @@ } } }, + "seq-queue": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/seq-queue/-/seq-queue-0.0.5.tgz", + "integrity": "sha1-1WgS4cAXpuTnw+Ojeh2m143TyT4=" + }, + "sequelize": { + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/sequelize/-/sequelize-4.35.0.tgz", + "integrity": "sha512-U/pMHkxzisEQQnZ18dh2qiKhdhF7/b+IH2vhQ9PFisHBcYRcaivt2y9jhUx/ZCUAgrfgAL1Bv24hpVzVBsSv8g==", + "requires": { + "bluebird": "^3.5.0", + "cls-bluebird": "^2.1.0", + "debug": "^3.1.0", + "depd": "^1.1.0", + "dottie": "^2.0.0", + "generic-pool": "^3.4.0", + "inflection": "1.12.0", + "lodash": "^4.17.1", + "moment": "^2.20.0", + "moment-timezone": "^0.5.14", + "retry-as-promised": "^2.3.2", + "semver": "^5.5.0", + "terraformer-wkt-parser": "^1.1.2", + "toposort-class": "^1.0.1", + "uuid": "^3.2.1", + "validator": "^9.4.1", + "wkx": "^0.4.1" + }, + "dependencies": { + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } + } + }, "serve-static": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", @@ -5877,6 +6185,11 @@ "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", "dev": true }, + "shimmer": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/shimmer/-/shimmer-1.2.1.tgz", + "integrity": "sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==" + }, "signal-exit": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", @@ -6270,6 +6583,23 @@ "resolved": "https://registry.npmjs.org/taffydb/-/taffydb-2.6.2.tgz", "integrity": "sha1-fLy2S1oUG2ou/CxdLGe04VCyomg=" }, + "terraformer": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/terraformer/-/terraformer-1.0.9.tgz", + "integrity": "sha512-YlmQ1fsMWTkKGDGibCRWgmLzrpDRUr63Q025LJ/taYQ6j1Yb8q9McKF7NBi6ACAyUXO6F/bl9w6v4MY307y5Ag==", + "requires": { + "@types/geojson": "^1.0.0" + } + }, + "terraformer-wkt-parser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/terraformer-wkt-parser/-/terraformer-wkt-parser-1.2.0.tgz", + "integrity": "sha512-QU3iA54St5lF8Za1jg1oj4NYc8sn5tCZ08aNSWDeGzrsaV48eZk1iAVWasxhNspYBoCqdHuoot1pUTUrE1AJ4w==", + "requires": { + "@types/geojson": "^1.0.0", + "terraformer": "~1.0.5" + } + }, "test-exclude": { "version": "5.2.3", "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-5.2.3.tgz", @@ -6362,6 +6692,11 @@ "hoek": "6.x.x" } }, + "toposort-class": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toposort-class/-/toposort-class-1.0.1.tgz", + "integrity": "sha1-f/0feMi+KMO6Rc1OGj9e4ZO9mYg=" + }, "tough-cookie": { "version": "2.4.3", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", @@ -6619,6 +6954,11 @@ "spdx-expression-parse": "^3.0.0" } }, + "validator": { + "version": "9.4.1", + "resolved": "https://registry.npmjs.org/validator/-/validator-9.4.1.tgz", + "integrity": "sha512-YV5KjzvRmSyJ1ee/Dm5UED0G+1L4GZnLN3w6/T+zZm8scVua4sOhYKWTUrKa0H/tMiJyO9QLHMPN+9mB/aMunA==" + }, "vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", @@ -6642,6 +6982,14 @@ "isexe": "^2.0.0" } }, + "wkx": { + "version": "0.4.8", + "resolved": "https://registry.npmjs.org/wkx/-/wkx-0.4.8.tgz", + "integrity": "sha512-ikPXMM9IR/gy/LwiOSqWlSL3X/J5uk9EO2hHNRXS41eTLXaUFEVw9fn/593jW/tE5tedNg8YjT5HkCa4FqQZyQ==", + "requires": { + "@types/node": "*" + } + }, "wordwrap": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", @@ -6661,6 +7009,11 @@ "mkdirp": "^0.5.1" } }, + "x-xss-protection": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/x-xss-protection/-/x-xss-protection-1.2.0.tgz", + "integrity": "sha512-xN0kV+8XfOQM2OPPBdEbGtbvJNNP1pvZR7sE6d44cjJFQG4OiGDdienPg5iOUGswBTiGbBvtYDURd30BMJwwqg==" + }, "xmlcreate": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/xmlcreate/-/xmlcreate-2.0.1.tgz", diff --git a/package.json b/package.json index 1f0e48f..6ed40f3 100644 --- a/package.json +++ b/package.json @@ -34,6 +34,7 @@ "coveralls": "^3.0.2", "dotenv": "^6.2.0", "express": "^4.16.4", + "helmet": "^3.20.0", "istanbul": "^0.4.5", "joi": "^14.0.6", "jsdoc": "^3.5.5", @@ -41,10 +42,11 @@ "mocha": "^5.2.0", "moment": "^2.22.2", "mysql": "^2.17.1", + "mysql2": "^1.6.1", "nodemailer": "^4.6.8", "nyc": "^13.1.0", + "sequelize": "4.35.0", "swagger-ui-express": "^4.0.1", - "uuidv4": "^2.0.0", - "sequelize": "4.35.0" + "uuidv4": "^2.0.0" } }