From 5a64568824bc9507691e7eadbdd63c99ff6c4926 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Y=C3=BBki=20Vachot?= Date: Fri, 29 Oct 2021 11:22:24 +0200 Subject: [PATCH 1/5] Update --- .gitignore | 1 + backend/Dockerfile | 1 + backend/app/config/mongodb.config.js | 3 + backend/app/config/response.config.js | 9 + backend/app/config/sessionJWT.config.js | 67 ++++ .../app/controllers/tutorial.controller.js | 117 +++++++ backend/app/controllers/user.controller.js | 148 +++++++++ backend/app/jwtRS256.key.pub | 14 + backend/app/jwtRS256.sh | 8 + backend/app/models/mongodb.model.js | 12 + backend/app/models/tutorial.model.js | 17 + backend/app/models/user.model.js | 18 ++ backend/app/routes/tutorial.routes.js | 28 ++ backend/app/routes/user.routes.js | 27 ++ backend/config.js | 13 - backend/keys/jwtRS256.sh | 5 - backend/mongodbConnect.js | 20 -- backend/mongodbQueries | 62 ---- backend/package-lock.json | 302 ++++++++++++------ backend/package.json | 3 +- backend/server.js | 19 +- docker-compose.yml | 2 +- 22 files changed, 702 insertions(+), 194 deletions(-) create mode 100644 backend/app/config/mongodb.config.js create mode 100644 backend/app/config/response.config.js create mode 100644 backend/app/config/sessionJWT.config.js create mode 100644 backend/app/controllers/tutorial.controller.js create mode 100644 backend/app/controllers/user.controller.js create mode 100644 backend/app/jwtRS256.key.pub create mode 100644 backend/app/jwtRS256.sh create mode 100644 backend/app/models/mongodb.model.js create mode 100644 backend/app/models/tutorial.model.js create mode 100644 backend/app/models/user.model.js create mode 100644 backend/app/routes/tutorial.routes.js create mode 100644 backend/app/routes/user.routes.js delete mode 100644 backend/config.js delete mode 100644 backend/keys/jwtRS256.sh delete mode 100644 backend/mongodbConnect.js delete mode 100644 backend/mongodbQueries diff --git a/.gitignore b/.gitignore index 4e6d622..3e701ca 100644 --- a/.gitignore +++ b/.gitignore @@ -40,6 +40,7 @@ npm-debug.log yarn-error.log testem.log /typings +*.env # System Files .DS_Store diff --git a/backend/Dockerfile b/backend/Dockerfile index 047823e..086b40b 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -3,4 +3,5 @@ WORKDIR /app-backend COPY ["package.json", "package-lock.json*", "./"] RUN npm install COPY . . +CMD ./app/jwtRS256.sh CMD node server.js diff --git a/backend/app/config/mongodb.config.js b/backend/app/config/mongodb.config.js new file mode 100644 index 0000000..0914e67 --- /dev/null +++ b/backend/app/config/mongodb.config.js @@ -0,0 +1,3 @@ +module.exports = { + url: "mongodb://127.0.0.1:27017/polynotfound" +}; diff --git a/backend/app/config/response.config.js b/backend/app/config/response.config.js new file mode 100644 index 0000000..625a6cc --- /dev/null +++ b/backend/app/config/response.config.js @@ -0,0 +1,9 @@ +function sendMessage (res, successCode, data) { + return res.status(200).json({ status: 'success', successCode: successCode, data: data }); +} + +function sendError (res, statusCode, errorCode, reason) { + return res.status(statusCode).json({ status: 'error', errorCode: errorCode, reason: reason }); +} + +module.exports = { sendMessage, sendError }; diff --git a/backend/app/config/sessionJWT.config.js b/backend/app/config/sessionJWT.config.js new file mode 100644 index 0000000..5f525b5 --- /dev/null +++ b/backend/app/config/sessionJWT.config.js @@ -0,0 +1,67 @@ +const sessionJWTConfig = require ('jsonwebtoken'); +require('dotenv').config({ path: './app/.env' }); +const {sendError, sendMessage} = require ("./response.config"); + +if(process.env.JWTRS256_PRIVATE_KEY === undefined || process.env.JWTRS256_PUBLIC_KEY === undefined){ + console.log('Error Env Variables'); + process.exit(); +} + +console.log('Env variables received'); +const JWTRS256_PRIVATE_KEY = Buffer.from(process.env.JWTRS256_PRIVATE_KEY, 'base64'); +const JWTRS256_PUBLIC_KEY = Buffer.from(process.env.JWTRS256_PUBLIC_KEY, 'base64'); + +function createSessionJWT (mail) { + return sessionJWTConfig.sign( + { + mail: mail, + midExp: Math.floor(Date.now() / 1000) + 1800 + }, + JWTRS256_PRIVATE_KEY, + { + algorithm: 'RS256', + expiresIn: '1h' + } + ); +} + +function createSessionCookie(req, res, payload) { + let jwtToken; + if ((typeof payload.mail !== 'undefined') && + (typeof payload.midExp !== 'undefined') && + (Math.floor(Date.now() / 1000) <= payload.midExp)) { + jwtToken = req.headers.cookie; + } + else { + jwtToken = createSessionJWT(payload.mail); + } + res.cookie('SESSIONID', jwtToken, {httpOnly:true, secure:false}); +} +module.exports.createSessionCookie = createSessionCookie; + +function decodeSessionCookie(sessionid, res) { + if (typeof sessionid === 'undefined') { + return { mail: -1 }; + } + try { + const token = sessionJWTConfig.verify( + sessionid, + JWTRS256_PUBLIC_KEY, + {algorithms: ['RS256']}); + return sendMessage(res,1,{token: token}); + } + catch (err) { + return sendError(res,-1,{mail: -1}); + } +} +module.exports.decodeSessionCookie = decodeSessionCookie; + +function getSession (sessionid, res) { + return decodeSessionCookie(sessionid, res); +} +module.exports.getSession = getSession; + +function setSessionCookie (req, res, session) { + createSessionCookie(req, res, session); +} +module.exports.setSessionCookie = setSessionCookie; diff --git a/backend/app/controllers/tutorial.controller.js b/backend/app/controllers/tutorial.controller.js new file mode 100644 index 0000000..222aa0c --- /dev/null +++ b/backend/app/controllers/tutorial.controller.js @@ -0,0 +1,117 @@ +const db = require("../models/mongodb.model"); +const {sendError, sendMessage} = require ("../config/response.config"); +const Tutorial = db.tutorials; + +// Create and Save a new Tutorial +exports.create = (req, res) => { + // Validate request + if (!req.body.title) { + sendError(res, 400,-1,"Content can not be empty!" ); + } + + // Create a Tutorial + const tutorial = new Tutorial({ + title: req.body.title, + description: req.body.description, + published: req.body.published ? req.body.published : false + }); + + // Save Tutorial in the database + tutorial + .save(tutorial) + .then(data => { + sendMessage(res, 1, data) + }) + .catch(err => { + sendError(res, 500,-1,err.message || "Some error occurred while creating the Tutorial."); + }); +}; + +// Retrieve all Tutorials from the database. +exports.findAll = (req, res) => { + const title = req.query.title; + let condition = title ? { title: { $regex: new RegExp(title), $options: "i" } } : {}; + + Tutorial.find(condition) + .then(data => { + sendMessage(res, 1, data) + }) + .catch(err => { + sendError(res,500,-1,err.message || "Some error occurred while retrieving tutorials."); + }); +}; + +// Find a single Tutorial with an id +exports.findOne = (req, res) => { + const id = req.params.id; + + Tutorial.findById(id) + .then(data => { + if (!data) + sendError(res,404,-1,"Not found Tutorial with id " + id ); + else sendMessage(res, 1, data); + }) + .catch(err => { + sendError(res,500,-1,err.message || "Error retrieving Tutorial with id=" + id ); + }); +}; + +// Update a Tutorial by the id in the request +exports.update = (req, res) => { + if (!req.body) { + sendError(res,400,-1,"Data to update can not be empty!"); + } + + const id = req.params.id; + + Tutorial.findByIdAndUpdate(id, req.body, { useFindAndModify: false }) + .then(data => { + if (!data) { + sendError(res,404,-1,`Cannot update Tutorial with id=${id}. Maybe Tutorial was not found!`); + } else sendMessage(res, 1, { message: "Tutorial was updated successfully." }); + }) + .catch(err => { + sendError(res,500,-1,err.message || "Error updating Tutorial with id=" + id); + }); +}; + +// Delete a Tutorial with the specified id in the request +exports.delete = (req, res) => { + const id = req.params.id; + + Tutorial.findByIdAndRemove(id) + .then(data => { + if (!data) { + sendError(res,404,-1,`Cannot delete Tutorial with id=${id}. Maybe Tutorial was not found!`); + } else { + sendMessage(res, 1, { message: "Tutorial was deleted successfully!" }); + } + }) + .catch(err => { + sendError(res,500,-1,err.message || "Could not delete Tutorial with id=" + id); + }); +}; + +// Delete all Tutorials from the database. +exports.deleteAll = (req, res) => { + Tutorial.deleteMany({}) + .then(data => { + sendMessage(res, 1, { + message: `${data.deletedCount} Tutorials were deleted successfully!` + }); + }) + .catch(err => { + sendError(res,500,-1,err.message || "Some error occurred while removing all tutorials."); + }); +}; + +// Find all published Tutorials +exports.findAllPublished = (req, res) => { + Tutorial.find({ published: true }) + .then(data => { + sendMessage(res, 1, data); + }) + .catch(err => { + sendError(res,500,-1,err.message || "Some error occurred while retrieving tutorials."); + }); +}; diff --git a/backend/app/controllers/user.controller.js b/backend/app/controllers/user.controller.js new file mode 100644 index 0000000..b0cc4cf --- /dev/null +++ b/backend/app/controllers/user.controller.js @@ -0,0 +1,148 @@ +const db = require("../models/mongodb.model"); +const {sendError, sendMessage} = require ("../config/response.config"); +const sessionJWT = require('../config/sessionJWT.config'); +const User = db.users; + + +// Authenticate an User +exports.auth = (req, res) => { + // Validate request + if (!req.body.mail || !req.body.hashPass) { + sendError(res, 400,-1,"Content can not be empty ! (mail and hashPass needed)"); + } else{ + // Check User in the database + User + .findOne({mail: req.body.mail, hashPass: req.body.hashPass}, [{count: {$size: "$_id"}}]) + .then(data => { + if (data !== null){ + sessionJWT.setSessionCookie(req, res, { mail: req.body.mail }); + return sendMessage(res, 1, true); + } else { + sessionJWT.setSessionCookie(req, res, { mail: -1 }); + return sendError(res, -1, "Invalid mail or password."); + } + }) + .catch(err => { + sendError(res, 500,-1,err.message || "Some error occurred while authenticating the User."); + }); + } +}; + +// Create and Save a new User +exports.create = (req, res) => { + // Validate request + if (!req.body.login || !req.body.hashPass || !req.body.mail || !req.body.role) { + sendError(res, 400,-1,"Content can not be empty ! (login, hashPass, mail and role needed"); + } + else{ + User.exists({login: req.body.login}, function (err, docs){ + if(err){ + sendError(res, 500,-1,err.message || "Some error occurred while checking if the User already exists."); + } else{ + if(docs === null) { + const user = new User({ + login: req.body.login, + hashPass: req.body.hashPass, + mail: req.body.mail, + role: req.body.role + }); + + // Save User in the database + user + .save(user) + .then(data => { + data.hashPass = undefined; // Hiding hashPass on return + sendMessage(res, 1, data) + }) + .catch(err => { + sendError(res, 500,-1,err.message || "Some error occurred while creating the User."); + }); + } else{ + sendError(res, 500, -1, err || "User already exists."); + } + } + }); + } +}; + +// Retrieve all Users from the database. +exports.findAll = (req, res) => { + const login = req.query.login; + let condition = login ? { login: { $regex: new RegExp(login), $options: "i" } } : {}; + + User.find(condition, {hashPass: false}) + .then(data => { + sendMessage(res, 1, data) + }) + .catch(err => { + sendError(res,500,-1,err.message || "Some error occurred while retrieving users."); + }); +}; + +// Find a single User with an id +exports.findOne = (req, res) => { + const id = req.params.id; + + User.findById(id, {hashPass: false}) + .then(data => { + if (data){ + sendMessage(res, 1, data); + } else { + sendError(res,404,-1,"Not found User with id " + id ); + } + }) + .catch(err => { + sendError(res,500,-1,err.message || "Error retrieving User with id=" + id ); + }); +}; + +// Update a User by the id in the request +exports.update = (req, res) => { + if (!req.body) { + sendError(res,400,-1,"Data to update can not be empty!"); + } else{ + const id = req.params.id; + + User.findByIdAndUpdate(id, req.body, { useFindAndModify: false }) + .then(data => { + if (data) { + sendMessage(res, 1, { message: "User was updated successfully." }); + } else { + sendError(res,404,-1,`Cannot update User with id=${id}. Maybe User was not found!`); + } + }) + .catch(err => { + sendError(res,500,-1,err.message || "Error updating User with id=" + id); + }); + } +}; + +// Delete a User with the specified id in the request +exports.delete = (req, res) => { + const id = req.params.id; + + User.findByIdAndRemove(id) + .then(data => { + if (data) { + sendMessage(res, 1, { message: "User was deleted successfully!" }); + } else { + sendError(res,404,-1,`Cannot delete User with id=${id}. Maybe User was not found!`); + } + }) + .catch(err => { + sendError(res,500,-1,err.message || "Could not delete User with id=" + id); + }); +}; + +// Delete all Users from the database. +exports.deleteAll = (req, res) => { + User.deleteMany({}) + .then(data => { + sendMessage(res, 1,{ + message: `${data.deletedCount} Users were deleted successfully!` + }); + }) + .catch(err => { + sendError(res,500,-1,err.message || "Some error occurred while removing all Users."); + }); +}; diff --git a/backend/app/jwtRS256.key.pub b/backend/app/jwtRS256.key.pub new file mode 100644 index 0000000..9b3b9a9 --- /dev/null +++ b/backend/app/jwtRS256.key.pub @@ -0,0 +1,14 @@ +-----BEGIN PUBLIC KEY----- +MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAyTaN1skc89wdcz8SLY9c +lkcARENbO40DncmcUZwQEq+EYR9BzUhjIzKJ6JetU+qGt4SJQkPAczQbw8+LaF6P +NT0QTF6E6BUgTZg1p98E/208AiFDnoqEjmlLdQN7ekttJXGDrVOTds9WMbn8lVpa +4EpVc+8CPDmrSTIC2YVSZmmektmFTSUA6411+5FGlq5oUdyKkToWYdn/ViJbYst8 +N48E2Vuh1ghY5t7oPWGzPibMc/6A+uDAF7+VVD8x5UydMZ9id+RxC7lhtDDvZeRM +BllHcnWfw0UMhVk8PC6/BenJ4I8HiOgyl4cypTvlevfbZjSoNJ4g/u/lDKpdqbBg +T76OksaYqvwvTrcvPdgF1f8l/7M9ESYZTMpxvqK6YvYC/MG2355fmZ1SeuqKfDt8 +rQXfXzesGSNmFNkm8mORHYiXBqyuNAwnSqRtP8qfoB4yXZ2W1HjUf24TvkvMrqwT +7PFg55c/f4LVdPjx52z30QzBJmcyVZgzXNOCG1KafwBibhriQmhdfiWogs824mwI +9w0vG2pPqSHRAa6N1y9JHSP1rIfu1jzRNFWTUuqyKgLYBE47HqxxJ21BwBryTVUz +8Ei+o05lJFkQX2/ISFYP2RunfUBccqmv0nEcGr+RSLTeqz5+WUTWs8tQxUItf2p6 +9Y30htlmCJlSnHn2JlaJWQUCAwEAAQ== +-----END PUBLIC KEY----- diff --git a/backend/app/jwtRS256.sh b/backend/app/jwtRS256.sh new file mode 100644 index 0000000..d410256 --- /dev/null +++ b/backend/app/jwtRS256.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash +ssh-keygen -t rsa -b 4096 -m PEM -f jwtRS256.key -q -N "" +openssl rsa -in jwtRS256.key -pubout -outform PEM -out jwtRS256.key.pub +rm .env +echo "JWTRS256_PRIVATE_KEY='`cat ./jwtRS256.key | base64 -w 0`'" >> .env +echo "JWTRS256_PUBLIC_KEY='`cat ./jwtRS256.key.pub | base64 -w 0`'" >> .env +source .env +rm jwtRS256.key diff --git a/backend/app/models/mongodb.model.js b/backend/app/models/mongodb.model.js new file mode 100644 index 0000000..974b911 --- /dev/null +++ b/backend/app/models/mongodb.model.js @@ -0,0 +1,12 @@ +const dbConfig = require("../config/mongodb.config"); + +const mongoose = require("mongoose"); +mongoose.Promise = global.Promise; + +const db = {}; +db.mongoose = mongoose; +db.url = dbConfig.url; +db.tutorials = require("./tutorial.model")(mongoose); +db.users = require("./user.model")(mongoose); + +module.exports = db; diff --git a/backend/app/models/tutorial.model.js b/backend/app/models/tutorial.model.js new file mode 100644 index 0000000..e5809f8 --- /dev/null +++ b/backend/app/models/tutorial.model.js @@ -0,0 +1,17 @@ +module.exports = mongoose => { + let schema = mongoose.Schema({ + title: String, + description: String, + published: Boolean + }, + { timestamps: true } + ); + + schema.method("toJSON", function() { + const { __v, _id, ...object } = this.toObject(); + object.id = _id; + return object; + }); + + return mongoose.model("tutorial", schema); +}; diff --git a/backend/app/models/user.model.js b/backend/app/models/user.model.js new file mode 100644 index 0000000..bf8a5c8 --- /dev/null +++ b/backend/app/models/user.model.js @@ -0,0 +1,18 @@ +module.exports = mongoose => { + let schema = mongoose.Schema({ + login: String, + hashPass: String, // WARNING: We don't want to send back the hashPass + mail: String, + role: Object + }, + { timestamps: true } + ); + + schema.method("toJSON", function() { + const { __v, _id, ...object } = this.toObject(); + object.id = _id; + return object; + }); + + return User = mongoose.model("user", schema); +}; diff --git a/backend/app/routes/tutorial.routes.js b/backend/app/routes/tutorial.routes.js new file mode 100644 index 0000000..5ee5f97 --- /dev/null +++ b/backend/app/routes/tutorial.routes.js @@ -0,0 +1,28 @@ +module.exports = app => { + const tutorials = require("../controllers/tutorial.controller.js"); + + let router = require("express").Router(); + + // Create a new Tutorial + router.post("/", tutorials.create); + + // Retrieve all Tutorials + router.get("/", tutorials.findAll); + + // Retrieve all published Tutorials + router.get("/published", tutorials.findAllPublished); + + // Retrieve a single Tutorial with id + router.get("/:id", tutorials.findOne); + + // Update a Tutorial with id + router.put("/:id", tutorials.update); + + // Delete a Tutorial with id + router.delete("/:id", tutorials.delete); + + // Create a new Tutorial + router.delete("/", tutorials.deleteAll); + + app.use('/api/tutorials', router); +}; diff --git a/backend/app/routes/user.routes.js b/backend/app/routes/user.routes.js new file mode 100644 index 0000000..7eee3e1 --- /dev/null +++ b/backend/app/routes/user.routes.js @@ -0,0 +1,27 @@ +const users = require("../controllers/user.controller"); +module.exports = app => { + let router = require("express").Router(); + + // Create a new User + router.post("/", users.create); + + // Retrieve all Users + router.get("/", users.findAll); + + // Retrieve a single User with id + router.get("/:id", users.findOne); + + // Update a User with id + router.put("/:id", users.update); + + // Delete a User with id + router.delete("/:id", users.delete); + + // Delete all Users + router.delete("/", users.deleteAll); + + // Authenticate a User + router.post("/auth", users.auth); + + app.use('/api/users', router); +}; diff --git a/backend/config.js b/backend/config.js deleted file mode 100644 index a200720..0000000 --- a/backend/config.js +++ /dev/null @@ -1,13 +0,0 @@ -const config = { - // paramètres de connexion à la base de données - mongodbDatabase: 'polynotfound', - mongodbHost: 'mongodb://mongodb:27017/', - // mongodbHost: 'mongodb://127.0.0.1:27017/', - charset: 'utf8', - mongodbLogin: '', - mongodbPassword: '', - - // les noms des tables - mongodbUtilisateurs: 'users' -}; -module.exports = config; diff --git a/backend/keys/jwtRS256.sh b/backend/keys/jwtRS256.sh deleted file mode 100644 index 5e1fe1e..0000000 --- a/backend/keys/jwtRS256.sh +++ /dev/null @@ -1,5 +0,0 @@ -ssh-keygen -t rsa -b 4096 -m PEM -f jwtRS256.key -# Don't add passphrase -openssl rsa -in jwtRS256.key -pubout -outform PEM -out jwtRS256.key.pub -cat jwtRS256.key -cat jwtRS256.key.pub diff --git a/backend/mongodbConnect.js b/backend/mongodbConnect.js deleted file mode 100644 index b823b9f..0000000 --- a/backend/mongodbConnect.js +++ /dev/null @@ -1,20 +0,0 @@ -const config = require('./config'); -const MongoClient = require( 'mongodb' ).MongoClient; -const uri = config.mongodbHost; -let db; - -module.exports = { - connectToServer: function( callback ) { - MongoClient.connect( uri, { useNewUrlParser: true, useUnifiedTopology: true }, function( err, client ) { - if(err) throw err; - console.log('mongodb-checkConnection'+client===undefined); - if (client !== undefined) console.log(client.isConnected()); - db = client.db(config.mongodbDatabase); - return callback( err ); - }); - }, - - getDB: function() { - return db; - } -}; diff --git a/backend/mongodbQueries b/backend/mongodbQueries deleted file mode 100644 index 00a2e5f..0000000 --- a/backend/mongodbQueries +++ /dev/null @@ -1,62 +0,0 @@ -const config = require('./config'); -const mongoDB = require ('./mongodbConnect').getDB(); - -function checkLoginQuery(login, password){ - // SELECT idUtilisateurs - // FROM utilisateurs - // WHERE login = ? AND password = ?; - return new Promise((resolve, reject) => { - resolve(mongoDB.collection(config.mongodbUtilisateurs).find( - {login: login, password: password}, - {projection: {_id: 1}}).count()); - }); -} -module.exports.checkLoginQuery = checkLoginQuery; - -function register(login, password){ - // INSERT INTO users(login, password) - return new Promise((resolve, reject) => { - mongoDB.collection(config.mongodbUtilisateurs).updateOne( - {'login': login}, - {$setOnInsert: { 'login': login, 'password': password}}, - {upsert:true},function(err,res){ - //console.log(res); - if(res !== undefined){ - if(typeof res.upsertedId !== 'undefined'){ - resolve(res.upsertedId); - }else{ - resolve(false); - } - } - }); - }); -} -module.exports.register = register; - -function getUsersQuery(username){ - return new Promise((resolve, reject) => { - mongoDB.collection(config.mongodbUtilisateurs).find( - { $and: [{'login': {$ne: 'Server'}}, {'login': {$ne: username}}]}, - {projection: {_id: 0, password: 0}} - ).toArray(function (err, result){ - if(err) throw err; - resolve(result); - }); - }); -} -module.exports.getUsersQuery = getUsersQuery - -function changePasswordQuery(login, password, newPassword){ - return new Promise((resolve, reject) => { - mongoDB.collection(config.mongodbUtilisateurs).findOneAndUpdate( - {'login': login, 'password': password}, - {$set: { 'login': login, 'password': newPassword}} - ,function(err,res){ - if(res !== undefined){ - console.log(res); - resolve(res.lastErrorObject.n === 1); - } - }); - }); -} -module.exports.changePasswordQuery = changePasswordQuery; diff --git a/backend/package-lock.json b/backend/package-lock.json index 14a0486..502d629 100644 --- a/backend/package-lock.json +++ b/backend/package-lock.json @@ -4,6 +4,25 @@ "lockfileVersion": 1, "requires": true, "dependencies": { + "@types/node": { + "version": "16.11.6", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.6.tgz", + "integrity": "sha512-ua7PgUoeQFjmWPcoo9khiPum3Pd60k4/2ZGXt18sm2Slk0W0xZTqt5Y0Ny1NyBiN1EVQ/+FaF9NcY4Qe6rwk5w==" + }, + "@types/webidl-conversions": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-6.1.1.tgz", + "integrity": "sha512-XAahCdThVuCFDQLT7R7Pk/vqeObFNL3YqRyFZg+AqAP/W1/w3xHaIxuW7WszQqTbIBOPRcItYJIou3i/mppu3Q==" + }, + "@types/whatwg-url": { + "version": "8.2.1", + "resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-8.2.1.tgz", + "integrity": "sha512-2YubE1sjj5ifxievI5Ge1sckb9k/Er66HyR2c+3+I6VDUUg1TLPdYYTEbQ+DjRkS4nTxMJhgWfSfMRD2sl2EYQ==", + "requires": { + "@types/node": "*", + "@types/webidl-conversions": "*" + } + }, "accepts": { "version": "1.3.7", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", @@ -18,14 +37,10 @@ "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" }, - "bl": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/bl/-/bl-2.2.1.tgz", - "integrity": "sha512-6Pesp1w0DEX1N550i/uGV/TqucVL4AM/pgThFSN/Qq9si1/DF9aIHs1BxD8V/QU0HoeHO6cQRTAuYnLPKq1e4g==", - "requires": { - "readable-stream": "^2.3.5", - "safe-buffer": "^5.1.1" - } + "base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" }, "body-parser": { "version": "1.19.0", @@ -42,12 +57,39 @@ "qs": "6.7.0", "raw-body": "2.4.0", "type-is": "~1.6.17" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } } }, "bson": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/bson/-/bson-1.1.6.tgz", - "integrity": "sha512-EvVNVeGo4tHxwi8L6bPj3y3itEvStdwvvlojVxxbyYfoaxJ6keLgrTuKdyfEAszFK+H3olzBuafE0yoh0D1gdg==" + "version": "4.5.3", + "resolved": "https://registry.npmjs.org/bson/-/bson-4.5.3.tgz", + "integrity": "sha512-qVX7LX79Mtj7B3NPLzCfBiCP6RAsjiV8N63DjlaVVpZW+PFoDTxQ4SeDbSpcqgE6mXksM5CAwZnXxxxn/XwC0g==", + "requires": { + "buffer": "^5.6.0" + } + }, + "buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } }, "buffer-equal-constant-time": { "version": "1.0.1", @@ -91,11 +133,6 @@ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" }, - "core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" - }, "cors": { "version": "2.8.5", "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", @@ -106,17 +143,17 @@ } }, "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", "requires": { - "ms": "2.0.0" + "ms": "2.1.2" } }, "denque": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/denque/-/denque-1.5.1.tgz", - "integrity": "sha512-XwE+iZ4D6ZUB7mfYRMb5wByE8L74HCn30FBN7sWnXksWc1LO1bPDl67pBR9o/kC4z/xSNAwkMYcGgqDV3BE3Hw==" + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/denque/-/denque-2.0.1.tgz", + "integrity": "sha512-tfiWc6BQLXNLpNiR5iGd0Ocu3P3VpxfzFiqubLgMfhfOw9WyvgJBd46CClNn9k3qfbjvT//0cf7AlYRX/OslMQ==" }, "depd": { "version": "1.1.2", @@ -128,6 +165,11 @@ "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" }, + "dotenv": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz", + "integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==" + }, "ecdsa-sig-formatter": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", @@ -191,6 +233,21 @@ "type-is": "~1.6.18", "utils-merge": "1.0.1", "vary": "~1.1.2" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } } }, "finalhandler": { @@ -205,6 +262,21 @@ "parseurl": "~1.3.3", "statuses": "~1.5.0", "unpipe": "~1.0.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } } }, "forwarded": { @@ -237,6 +309,11 @@ "safer-buffer": ">= 2.1.2 < 3" } }, + "ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" + }, "inherits": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", @@ -247,11 +324,6 @@ "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" - }, "jsonwebtoken": { "version": "8.5.1", "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz", @@ -267,13 +339,6 @@ "lodash.once": "^4.0.0", "ms": "^2.1.1", "semver": "^5.6.0" - }, - "dependencies": { - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - } } }, "jwa": { @@ -295,6 +360,11 @@ "safe-buffer": "^5.0.1" } }, + "kareem": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.3.2.tgz", + "integrity": "sha512-STHz9P7X2L4Kwn72fA4rGyqyXdmrMSdxqHx9IXon/FXluXieaFA6KJ2upcHAHxQPQ0LeM/OjLrhFxifHewOALQ==" + }, "lodash.includes": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", @@ -370,22 +440,60 @@ } }, "mongodb": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.7.2.tgz", - "integrity": "sha512-/Qi0LmOjzIoV66Y2JQkqmIIfFOy7ZKsXnQNlUXPFXChOw3FCdNqVD5zvci9ybm6pkMe/Nw+Rz9I0Zsk2a+05iQ==", + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-4.1.3.tgz", + "integrity": "sha512-lHvTqODBiSpuqjpCj48DOyYWS6Iq6ElJNUiH9HWdQtONyOfjgsKzJULipWduMGsSzaNO4nFi/kmlMFCLvjox/Q==", "requires": { - "bl": "^2.2.1", - "bson": "^1.1.4", - "denque": "^1.4.1", - "optional-require": "^1.1.8", - "safe-buffer": "^5.1.2", - "saslprep": "^1.0.0" + "bson": "^4.5.2", + "denque": "^2.0.1", + "mongodb-connection-string-url": "^2.0.0", + "saslprep": "^1.0.3" + } + }, + "mongodb-connection-string-url": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-2.1.0.tgz", + "integrity": "sha512-Qf9Zw7KGiRljWvMrrUFDdVqo46KIEiDuCzvEN97rh/PcKzk2bd6n9KuzEwBwW9xo5glwx69y1mI6s+jFUD/aIQ==", + "requires": { + "@types/whatwg-url": "^8.2.1", + "whatwg-url": "^9.1.0" + } + }, + "mongoose": { + "version": "6.0.12", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-6.0.12.tgz", + "integrity": "sha512-BvsZk7zEEhb1AgQFLtxN9C+7qgy5edRuA3ZDDwHU+kHG/HM44vI6FdKV5m6HVdAUeCHHQTiVv+YQh8BRsToSHw==", + "requires": { + "bson": "^4.2.2", + "kareem": "2.3.2", + "mongodb": "4.1.3", + "mpath": "0.8.4", + "mquery": "4.0.0", + "ms": "2.1.2", + "regexp-clone": "1.0.0", + "sift": "13.5.2", + "sliced": "1.0.1" + } + }, + "mpath": { + "version": "0.8.4", + "resolved": "https://registry.npmjs.org/mpath/-/mpath-0.8.4.tgz", + "integrity": "sha512-DTxNZomBcTWlrMW76jy1wvV37X/cNNxPW1y2Jzd4DZkAaC5ZGsm8bfGfNOthcDuRJujXLqiuS6o3Tpy0JEoh7g==" + }, + "mquery": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mquery/-/mquery-4.0.0.tgz", + "integrity": "sha512-nGjm89lHja+T/b8cybAby6H0YgA4qYC/lx6UlwvHGqvTq8bDaNeCwl1sY8uRELrNbVWJzIihxVd+vphGGn1vBw==", + "requires": { + "debug": "4.x", + "regexp-clone": "^1.0.0", + "sliced": "1.0.1" } }, "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "negotiator": { "version": "0.6.2", @@ -405,14 +513,6 @@ "ee-first": "1.1.1" } }, - "optional-require": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/optional-require/-/optional-require-1.1.8.tgz", - "integrity": "sha512-jq83qaUb0wNg9Krv1c5OQ+58EK+vHde6aBPzLvPPqJm89UQWsvSuFy9X/OSNJnFeSOKo7btE0n8Nl2+nE+z5nA==", - "requires": { - "require-at": "^1.0.6" - } - }, "parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", @@ -423,11 +523,6 @@ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" - }, "proxy-addr": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", @@ -437,6 +532,11 @@ "ipaddr.js": "1.9.1" } }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" + }, "qs": { "version": "6.7.0", "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", @@ -458,24 +558,10 @@ "unpipe": "1.0.0" } }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "require-at": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/require-at/-/require-at-1.0.6.tgz", - "integrity": "sha512-7i1auJbMUrXEAZCOQ0VNJgmcT2VOKPRl2YGJwgpHpC9CE91Mv4/4UYIUm4chGJaI381ZDq1JUicFii64Hapd8g==" + "regexp-clone": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/regexp-clone/-/regexp-clone-1.0.0.tgz", + "integrity": "sha512-TuAasHQNamyyJ2hb97IuBEif4qBHGjPHBS64sZwytpLEqtBQ1gPJTnOaQ6qmpET16cK14kkjbazl6+p0RRv0yw==" }, "safe-buffer": { "version": "5.1.2", @@ -521,6 +607,21 @@ "statuses": "~1.5.0" }, "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + }, + "dependencies": { + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, "ms": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", @@ -544,6 +645,16 @@ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" }, + "sift": { + "version": "13.5.2", + "resolved": "https://registry.npmjs.org/sift/-/sift-13.5.2.tgz", + "integrity": "sha512-+gxdEOMA2J+AI+fVsCqeNn7Tgx3M9ZN9jdi95939l1IJ8cZsqS8sqpJyOkic2SJk+1+98Uwryt/gL6XDaV+UZA==" + }, + "sliced": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sliced/-/sliced-1.0.1.tgz", + "integrity": "sha1-CzpmK10Ewxd7GSa+qCsD+Dei70E=" + }, "sparse-bitfield": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", @@ -558,19 +669,19 @@ "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "requires": { - "safe-buffer": "~5.1.0" - } - }, "toidentifier": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==" }, + "tr46": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz", + "integrity": "sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==", + "requires": { + "punycode": "^2.1.1" + } + }, "type-is": { "version": "1.6.18", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", @@ -585,11 +696,6 @@ "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, "utils-merge": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", @@ -599,6 +705,20 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" + }, + "webidl-conversions": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", + "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==" + }, + "whatwg-url": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-9.1.0.tgz", + "integrity": "sha512-CQ0UcrPHyomtlOCot1TL77WyMIm/bCwrJ2D6AOKGwEczU9EpyoqAokfqrf/MioU9kHcMsmJZcg1egXix2KYEsA==", + "requires": { + "tr46": "^2.1.0", + "webidl-conversions": "^6.1.0" + } } } } diff --git a/backend/package.json b/backend/package.json index 7d2fdf0..1316b91 100644 --- a/backend/package.json +++ b/backend/package.json @@ -12,8 +12,9 @@ "body-parser": "^1.19.0", "cookie-parser": "^1.4.5", "cors": "^2.8.5", + "dotenv": "^10.0.0", "express": "^4.17.1", "jsonwebtoken": "^8.5.1", - "mongodb": "^3.6.9" + "mongoose": "^6.0.12" } } diff --git a/backend/server.js b/backend/server.js index 4a3868a..9e913c0 100644 --- a/backend/server.js +++ b/backend/server.js @@ -12,7 +12,24 @@ app.use(bodyParser.json()); const cors = require('cors'); app.use(cors({origin: 'http://localhost:4200', credentials: true})); +const db = require("./app/models/mongodb.model"); +db.mongoose + .connect(db.url, { + useNewUrlParser: true, + useUnifiedTopology: true + }, function (err){ + if(err){ + console.log("Cannot connect to the database!", err); + process.exit(); + } else{ + console.log("Connected to the database!", db.url); + } + }); + +require("./app/config/sessionJWT.config"); +require("./app/routes/tutorial.routes")(app); +require("./app/routes/user.routes")(app); + app.listen(port, '0.0.0.0',() => { console.log (`listening on port ${port}`); }); - diff --git a/docker-compose.yml b/docker-compose.yml index f5fded0..15b85cd 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -6,7 +6,7 @@ services: build: . command: ng serve --host 0.0.0.0 volumes: - - ./frontend:/data/frontend/ + - ./src:/data/frontend/ - ./node_modules:/data/frontend/node_modules ports: - 4200:4200 From a748b9313394e1166c03d48430d5c58733604c40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Y=C3=BBki=20Vachot?= Date: Fri, 29 Oct 2021 23:54:19 +0200 Subject: [PATCH 2/5] Update --- backend/app/config/checkFormat.config.js | 9 +++++ backend/app/config/response.config.js | 4 +- backend/app/config/sessionJWT.config.js | 44 ++++++++++++++++------ backend/app/controllers/user.controller.js | 43 +++++++++++++++------ backend/app/models/user.model.js | 2 +- backend/app/routes/user.routes.js | 3 ++ backend/package.json | 3 +- 7 files changed, 81 insertions(+), 27 deletions(-) create mode 100644 backend/app/config/checkFormat.config.js diff --git a/backend/app/config/checkFormat.config.js b/backend/app/config/checkFormat.config.js new file mode 100644 index 0000000..6b74fe0 --- /dev/null +++ b/backend/app/config/checkFormat.config.js @@ -0,0 +1,9 @@ +const {sendError} = require ("./response.config"); + +function checkFormat(req, res){ + if(req.get('Content-Type') !== 'application/json') { + return sendError(res, 401, -1, "Invalid header format (please use JSON)"); + } + return true; // Is valid +} +module.exports = checkFormat diff --git a/backend/app/config/response.config.js b/backend/app/config/response.config.js index 625a6cc..dcf5145 100644 --- a/backend/app/config/response.config.js +++ b/backend/app/config/response.config.js @@ -1,9 +1,9 @@ function sendMessage (res, successCode, data) { - return res.status(200).json({ status: 'success', successCode: successCode, data: data }); + res.status(200).json({ status: 'success', successCode: successCode, data: data }); } function sendError (res, statusCode, errorCode, reason) { - return res.status(statusCode).json({ status: 'error', errorCode: errorCode, reason: reason }); + res.status(statusCode).json({ status: 'error', errorCode: errorCode, reason: reason }); } module.exports = { sendMessage, sendError }; diff --git a/backend/app/config/sessionJWT.config.js b/backend/app/config/sessionJWT.config.js index 5f525b5..0a50b10 100644 --- a/backend/app/config/sessionJWT.config.js +++ b/backend/app/config/sessionJWT.config.js @@ -1,6 +1,6 @@ const sessionJWTConfig = require ('jsonwebtoken'); require('dotenv').config({ path: './app/.env' }); -const {sendError, sendMessage} = require ("./response.config"); +const {sendError} = require ("./response.config"); if(process.env.JWTRS256_PRIVATE_KEY === undefined || process.env.JWTRS256_PUBLIC_KEY === undefined){ console.log('Error Env Variables'); @@ -8,8 +8,9 @@ if(process.env.JWTRS256_PRIVATE_KEY === undefined || process.env.JWTRS256_PUBLIC } console.log('Env variables received'); -const JWTRS256_PRIVATE_KEY = Buffer.from(process.env.JWTRS256_PRIVATE_KEY, 'base64'); -const JWTRS256_PUBLIC_KEY = Buffer.from(process.env.JWTRS256_PUBLIC_KEY, 'base64'); +const JWTRS256_PRIVATE_KEY = Buffer.from(process.env.JWTRS256_PRIVATE_KEY, 'base64').toString('utf-8'); +const JWTRS256_PUBLIC_KEY = Buffer.from(process.env.JWTRS256_PUBLIC_KEY, 'base64').toString('utf-8'); + function createSessionJWT (mail) { return sessionJWTConfig.sign( @@ -37,31 +38,50 @@ function createSessionCookie(req, res, payload) { } res.cookie('SESSIONID', jwtToken, {httpOnly:true, secure:false}); } -module.exports.createSessionCookie = createSessionCookie; -function decodeSessionCookie(sessionid, res) { +function decodeSessionCookie(sessionid) { if (typeof sessionid === 'undefined') { - return { mail: -1 }; + return {mail: -1}; } try { const token = sessionJWTConfig.verify( sessionid, JWTRS256_PUBLIC_KEY, {algorithms: ['RS256']}); - return sendMessage(res,1,{token: token}); + return {token: token}; } catch (err) { - return sendError(res,-1,{mail: -1}); + return {mail: -1}; } } -module.exports.decodeSessionCookie = decodeSessionCookie; -function getSession (sessionid, res) { - return decodeSessionCookie(sessionid, res); +function getSession(sessionid) { + return decodeSessionCookie(sessionid); } -module.exports.getSession = getSession; +module.exports.getSession = getSession function setSessionCookie (req, res, session) { createSessionCookie(req, res, session); } module.exports.setSessionCookie = setSessionCookie; + +function getMail(session) { + if (typeof session === 'undefined' || typeof session.token === 'undefined') return -1; + return session.token; +} +module.exports.getMail = getMail; + +function checkLogin(req, res){ + if(typeof req.cookies !== 'undefined'){ + const session = getSession(req.cookies.SESSIONID); + const token = getMail(session); + if(token.mail === 'undefined' || token.mail === -1){ + return sendError(res, 500, -1, "User not authenticated."); + } else{ + return token; + } + } else { + return sendError(res, 500, -1, "Cookies don't exist."); + } +} +module.exports.checkLogin = checkLogin; diff --git a/backend/app/controllers/user.controller.js b/backend/app/controllers/user.controller.js index b0cc4cf..9659cef 100644 --- a/backend/app/controllers/user.controller.js +++ b/backend/app/controllers/user.controller.js @@ -1,11 +1,13 @@ const db = require("../models/mongodb.model"); const {sendError, sendMessage} = require ("../config/response.config"); +const checkFormat = require("../config/checkFormat.config"); const sessionJWT = require('../config/sessionJWT.config'); +const {checkLogin} = require("../config/sessionJWT.config"); const User = db.users; - // Authenticate an User exports.auth = (req, res) => { + checkFormat(req, res); // Validate request if (!req.body.mail || !req.body.hashPass) { sendError(res, 400,-1,"Content can not be empty ! (mail and hashPass needed)"); @@ -19,7 +21,7 @@ exports.auth = (req, res) => { return sendMessage(res, 1, true); } else { sessionJWT.setSessionCookie(req, res, { mail: -1 }); - return sendError(res, -1, "Invalid mail or password."); + return sendError(res, 500, -1, "Invalid mail or password."); } }) .catch(err => { @@ -28,8 +30,19 @@ exports.auth = (req, res) => { } }; +// Disconnect an User +exports.disconnect = (req, res) => { + let token; + if(checkFormat(req, res) && (token = checkLogin(req, res))) { + console.log(token); + sessionJWT.setSessionCookie(req, res, {mail: -1}); + return sendMessage(res, 1, {message: "User disconnected"}); + } +}; + // Create and Save a new User exports.create = (req, res) => { + checkFormat(req, res); // Validate request if (!req.body.login || !req.body.hashPass || !req.body.mail || !req.body.role) { sendError(res, 400,-1,"Content can not be empty ! (login, hashPass, mail and role needed"); @@ -67,20 +80,25 @@ exports.create = (req, res) => { // Retrieve all Users from the database. exports.findAll = (req, res) => { - const login = req.query.login; - let condition = login ? { login: { $regex: new RegExp(login), $options: "i" } } : {}; + let token; + if(checkFormat(req, res) && (token = checkLogin(req, res))){ + console.log(token); + const login = req.query.login; + let condition = login ? { login: { $regex: new RegExp(login), $options: "i" } } : {}; - User.find(condition, {hashPass: false}) - .then(data => { - sendMessage(res, 1, data) - }) - .catch(err => { - sendError(res,500,-1,err.message || "Some error occurred while retrieving users."); - }); + User.find(condition, {hashPass: false}) + .then(data => { + sendMessage(res, 1, data) + }) + .catch(err => { + sendError(res,500,-1,err.message || "Some error occurred while retrieving users."); + }); + } }; // Find a single User with an id exports.findOne = (req, res) => { + checkFormat(req, res); const id = req.params.id; User.findById(id, {hashPass: false}) @@ -98,6 +116,7 @@ exports.findOne = (req, res) => { // Update a User by the id in the request exports.update = (req, res) => { + checkFormat(req, res); if (!req.body) { sendError(res,400,-1,"Data to update can not be empty!"); } else{ @@ -119,6 +138,7 @@ exports.update = (req, res) => { // Delete a User with the specified id in the request exports.delete = (req, res) => { + checkFormat(req, res); const id = req.params.id; User.findByIdAndRemove(id) @@ -136,6 +156,7 @@ exports.delete = (req, res) => { // Delete all Users from the database. exports.deleteAll = (req, res) => { + checkFormat(req, res); User.deleteMany({}) .then(data => { sendMessage(res, 1,{ diff --git a/backend/app/models/user.model.js b/backend/app/models/user.model.js index bf8a5c8..fe29d74 100644 --- a/backend/app/models/user.model.js +++ b/backend/app/models/user.model.js @@ -14,5 +14,5 @@ module.exports = mongoose => { return object; }); - return User = mongoose.model("user", schema); + return mongoose.model("user", schema); }; diff --git a/backend/app/routes/user.routes.js b/backend/app/routes/user.routes.js index 7eee3e1..b3ba76f 100644 --- a/backend/app/routes/user.routes.js +++ b/backend/app/routes/user.routes.js @@ -23,5 +23,8 @@ module.exports = app => { // Authenticate a User router.post("/auth", users.auth); + // Disconnect a User + router.delete("/auth/disconnect", users.disconnect); + app.use('/api/users', router); }; diff --git a/backend/package.json b/backend/package.json index 1316b91..15a6c33 100644 --- a/backend/package.json +++ b/backend/package.json @@ -16,5 +16,6 @@ "express": "^4.17.1", "jsonwebtoken": "^8.5.1", "mongoose": "^6.0.12" - } + }, + "devDependencies": {} } From e87c4bb14604a3401d803b7d8a66f8483a58ef71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Y=C3=BBki=20Vachot?= Date: Sat, 30 Oct 2021 00:40:51 +0200 Subject: [PATCH 3/5] Remove tutorials & add auth manager --- backend/app/config/response.config.js | 8 +- backend/app/config/sessionJWT.config.js | 36 ++++-- .../app/controllers/tutorial.controller.js | 117 ------------------ backend/app/controllers/user.controller.js | 31 +++-- backend/app/models/mongodb.model.js | 1 - backend/app/models/tutorial.model.js | 17 --- backend/app/models/user.model.js | 5 +- backend/app/routes/tutorial.routes.js | 28 ----- backend/server.js | 1 - 9 files changed, 46 insertions(+), 198 deletions(-) delete mode 100644 backend/app/controllers/tutorial.controller.js delete mode 100644 backend/app/models/tutorial.model.js delete mode 100644 backend/app/routes/tutorial.routes.js diff --git a/backend/app/config/response.config.js b/backend/app/config/response.config.js index dcf5145..4278756 100644 --- a/backend/app/config/response.config.js +++ b/backend/app/config/response.config.js @@ -1,9 +1,9 @@ -function sendMessage (res, successCode, data) { - res.status(200).json({ status: 'success', successCode: successCode, data: data }); +function sendMessage (res, successCode, data, token=null) { + res.status(200).json({ status: 'success', successCode: successCode, token: token, data: data }); } -function sendError (res, statusCode, errorCode, reason) { - res.status(statusCode).json({ status: 'error', errorCode: errorCode, reason: reason }); +function sendError (res, statusCode, errorCode, reason, token=null) { + res.status(statusCode).json({ status: 'error', errorCode: errorCode, data: { token: token, reason: reason }}); } module.exports = { sendMessage, sendError }; diff --git a/backend/app/config/sessionJWT.config.js b/backend/app/config/sessionJWT.config.js index 0a50b10..b5b76cb 100644 --- a/backend/app/config/sessionJWT.config.js +++ b/backend/app/config/sessionJWT.config.js @@ -12,10 +12,11 @@ const JWTRS256_PRIVATE_KEY = Buffer.from(process.env.JWTRS256_PRIVATE_KEY, 'base const JWTRS256_PUBLIC_KEY = Buffer.from(process.env.JWTRS256_PUBLIC_KEY, 'base64').toString('utf-8'); -function createSessionJWT (mail) { +function createSessionJWT (login, role) { return sessionJWTConfig.sign( { - mail: mail, + login: login, + role: role, midExp: Math.floor(Date.now() / 1000) + 1800 }, JWTRS256_PRIVATE_KEY, @@ -28,20 +29,21 @@ function createSessionJWT (mail) { function createSessionCookie(req, res, payload) { let jwtToken; - if ((typeof payload.mail !== 'undefined') && - (typeof payload.midExp !== 'undefined') && + if (typeof payload.login !== 'undefined' && + typeof payload.role !== 'undefined' && + typeof payload.midExp !== 'undefined' && (Math.floor(Date.now() / 1000) <= payload.midExp)) { jwtToken = req.headers.cookie; } else { - jwtToken = createSessionJWT(payload.mail); + jwtToken = createSessionJWT(payload.login, payload.role); } res.cookie('SESSIONID', jwtToken, {httpOnly:true, secure:false}); } function decodeSessionCookie(sessionid) { if (typeof sessionid === 'undefined') { - return {mail: -1}; + return {login: -1, role: -1}; } try { const token = sessionJWTConfig.verify( @@ -51,7 +53,7 @@ function decodeSessionCookie(sessionid) { return {token: token}; } catch (err) { - return {mail: -1}; + return {login: -1, role: -1}; } } @@ -65,20 +67,28 @@ function setSessionCookie (req, res, session) { } module.exports.setSessionCookie = setSessionCookie; -function getMail(session) { +function getToken(session) { if (typeof session === 'undefined' || typeof session.token === 'undefined') return -1; return session.token; } -module.exports.getMail = getMail; +module.exports.getToken = getToken; -function checkLogin(req, res){ +function checkLogin(req, res, role=null){ if(typeof req.cookies !== 'undefined'){ const session = getSession(req.cookies.SESSIONID); - const token = getMail(session); - if(token.mail === 'undefined' || token.mail === -1){ + const token = getToken(session); + if(token.login === 'undefined' || token.login === -1){ return sendError(res, 500, -1, "User not authenticated."); } else{ - return token; + if(role === null){ + return token; + } else{ + if(token.role !== 'undefined' && token.role === role){ + return token; + } else{ + return sendError(res, 500, -1, "User doesn't have permission.", token); + } + } } } else { return sendError(res, 500, -1, "Cookies don't exist."); diff --git a/backend/app/controllers/tutorial.controller.js b/backend/app/controllers/tutorial.controller.js deleted file mode 100644 index 222aa0c..0000000 --- a/backend/app/controllers/tutorial.controller.js +++ /dev/null @@ -1,117 +0,0 @@ -const db = require("../models/mongodb.model"); -const {sendError, sendMessage} = require ("../config/response.config"); -const Tutorial = db.tutorials; - -// Create and Save a new Tutorial -exports.create = (req, res) => { - // Validate request - if (!req.body.title) { - sendError(res, 400,-1,"Content can not be empty!" ); - } - - // Create a Tutorial - const tutorial = new Tutorial({ - title: req.body.title, - description: req.body.description, - published: req.body.published ? req.body.published : false - }); - - // Save Tutorial in the database - tutorial - .save(tutorial) - .then(data => { - sendMessage(res, 1, data) - }) - .catch(err => { - sendError(res, 500,-1,err.message || "Some error occurred while creating the Tutorial."); - }); -}; - -// Retrieve all Tutorials from the database. -exports.findAll = (req, res) => { - const title = req.query.title; - let condition = title ? { title: { $regex: new RegExp(title), $options: "i" } } : {}; - - Tutorial.find(condition) - .then(data => { - sendMessage(res, 1, data) - }) - .catch(err => { - sendError(res,500,-1,err.message || "Some error occurred while retrieving tutorials."); - }); -}; - -// Find a single Tutorial with an id -exports.findOne = (req, res) => { - const id = req.params.id; - - Tutorial.findById(id) - .then(data => { - if (!data) - sendError(res,404,-1,"Not found Tutorial with id " + id ); - else sendMessage(res, 1, data); - }) - .catch(err => { - sendError(res,500,-1,err.message || "Error retrieving Tutorial with id=" + id ); - }); -}; - -// Update a Tutorial by the id in the request -exports.update = (req, res) => { - if (!req.body) { - sendError(res,400,-1,"Data to update can not be empty!"); - } - - const id = req.params.id; - - Tutorial.findByIdAndUpdate(id, req.body, { useFindAndModify: false }) - .then(data => { - if (!data) { - sendError(res,404,-1,`Cannot update Tutorial with id=${id}. Maybe Tutorial was not found!`); - } else sendMessage(res, 1, { message: "Tutorial was updated successfully." }); - }) - .catch(err => { - sendError(res,500,-1,err.message || "Error updating Tutorial with id=" + id); - }); -}; - -// Delete a Tutorial with the specified id in the request -exports.delete = (req, res) => { - const id = req.params.id; - - Tutorial.findByIdAndRemove(id) - .then(data => { - if (!data) { - sendError(res,404,-1,`Cannot delete Tutorial with id=${id}. Maybe Tutorial was not found!`); - } else { - sendMessage(res, 1, { message: "Tutorial was deleted successfully!" }); - } - }) - .catch(err => { - sendError(res,500,-1,err.message || "Could not delete Tutorial with id=" + id); - }); -}; - -// Delete all Tutorials from the database. -exports.deleteAll = (req, res) => { - Tutorial.deleteMany({}) - .then(data => { - sendMessage(res, 1, { - message: `${data.deletedCount} Tutorials were deleted successfully!` - }); - }) - .catch(err => { - sendError(res,500,-1,err.message || "Some error occurred while removing all tutorials."); - }); -}; - -// Find all published Tutorials -exports.findAllPublished = (req, res) => { - Tutorial.find({ published: true }) - .then(data => { - sendMessage(res, 1, data); - }) - .catch(err => { - sendError(res,500,-1,err.message || "Some error occurred while retrieving tutorials."); - }); -}; diff --git a/backend/app/controllers/user.controller.js b/backend/app/controllers/user.controller.js index 9659cef..51a01d1 100644 --- a/backend/app/controllers/user.controller.js +++ b/backend/app/controllers/user.controller.js @@ -1,27 +1,26 @@ const db = require("../models/mongodb.model"); const {sendError, sendMessage} = require ("../config/response.config"); const checkFormat = require("../config/checkFormat.config"); -const sessionJWT = require('../config/sessionJWT.config'); -const {checkLogin} = require("../config/sessionJWT.config"); +const {checkLogin, setSessionCookie} = require("../config/sessionJWT.config"); const User = db.users; // Authenticate an User exports.auth = (req, res) => { checkFormat(req, res); // Validate request - if (!req.body.mail || !req.body.hashPass) { - sendError(res, 400,-1,"Content can not be empty ! (mail and hashPass needed)"); + if (!req.body.login || !req.body.hashPass) { + sendError(res, 400,-1,"Content can not be empty ! (login and hashPass needed)"); } else{ // Check User in the database User - .findOne({mail: req.body.mail, hashPass: req.body.hashPass}, [{count: {$size: "$_id"}}]) + .findOne({login: req.body.login, hashPass: req.body.hashPass}, {role: true}) .then(data => { if (data !== null){ - sessionJWT.setSessionCookie(req, res, { mail: req.body.mail }); + setSessionCookie(req, res, { login: req.body.login, role: data.role}); return sendMessage(res, 1, true); } else { - sessionJWT.setSessionCookie(req, res, { mail: -1 }); - return sendError(res, 500, -1, "Invalid mail or password."); + setSessionCookie(req, res, { login: -1, role: -1 }); + return sendError(res, 500, -1, "Invalid login or password."); } }) .catch(err => { @@ -35,17 +34,17 @@ exports.disconnect = (req, res) => { let token; if(checkFormat(req, res) && (token = checkLogin(req, res))) { console.log(token); - sessionJWT.setSessionCookie(req, res, {mail: -1}); - return sendMessage(res, 1, {message: "User disconnected"}); + setSessionCookie(req, res, {login: -1}); + return sendMessage(res, 1, {message: "User disconnected"}, token); } }; // Create and Save a new User exports.create = (req, res) => { - checkFormat(req, res); + checkFormat(req, res); // Validate request - if (!req.body.login || !req.body.hashPass || !req.body.mail || !req.body.role) { - sendError(res, 400,-1,"Content can not be empty ! (login, hashPass, mail and role needed"); + if (!req.body.login || !req.body.hashPass || !req.body.mail) { + sendError(res, 400,-1,"Content can not be empty ! (login, hashPass and mail needed"); } else{ User.exists({login: req.body.login}, function (err, docs){ @@ -81,17 +80,17 @@ exports.create = (req, res) => { // Retrieve all Users from the database. exports.findAll = (req, res) => { let token; - if(checkFormat(req, res) && (token = checkLogin(req, res))){ + if(checkFormat(req, res) && (token = checkLogin(req, res, 10))){ console.log(token); const login = req.query.login; let condition = login ? { login: { $regex: new RegExp(login), $options: "i" } } : {}; User.find(condition, {hashPass: false}) .then(data => { - sendMessage(res, 1, data) + sendMessage(res, 1, data, token) }) .catch(err => { - sendError(res,500,-1,err.message || "Some error occurred while retrieving users."); + sendError(res,500,-1,err.message || "Some error occurred while retrieving users.", token); }); } }; diff --git a/backend/app/models/mongodb.model.js b/backend/app/models/mongodb.model.js index 974b911..58cce74 100644 --- a/backend/app/models/mongodb.model.js +++ b/backend/app/models/mongodb.model.js @@ -6,7 +6,6 @@ mongoose.Promise = global.Promise; const db = {}; db.mongoose = mongoose; db.url = dbConfig.url; -db.tutorials = require("./tutorial.model")(mongoose); db.users = require("./user.model")(mongoose); module.exports = db; diff --git a/backend/app/models/tutorial.model.js b/backend/app/models/tutorial.model.js deleted file mode 100644 index e5809f8..0000000 --- a/backend/app/models/tutorial.model.js +++ /dev/null @@ -1,17 +0,0 @@ -module.exports = mongoose => { - let schema = mongoose.Schema({ - title: String, - description: String, - published: Boolean - }, - { timestamps: true } - ); - - schema.method("toJSON", function() { - const { __v, _id, ...object } = this.toObject(); - object.id = _id; - return object; - }); - - return mongoose.model("tutorial", schema); -}; diff --git a/backend/app/models/user.model.js b/backend/app/models/user.model.js index fe29d74..c9b97b5 100644 --- a/backend/app/models/user.model.js +++ b/backend/app/models/user.model.js @@ -3,7 +3,10 @@ module.exports = mongoose => { login: String, hashPass: String, // WARNING: We don't want to send back the hashPass mail: String, - role: Object + role: { + type: Number, + default: 0 + } }, { timestamps: true } ); diff --git a/backend/app/routes/tutorial.routes.js b/backend/app/routes/tutorial.routes.js deleted file mode 100644 index 5ee5f97..0000000 --- a/backend/app/routes/tutorial.routes.js +++ /dev/null @@ -1,28 +0,0 @@ -module.exports = app => { - const tutorials = require("../controllers/tutorial.controller.js"); - - let router = require("express").Router(); - - // Create a new Tutorial - router.post("/", tutorials.create); - - // Retrieve all Tutorials - router.get("/", tutorials.findAll); - - // Retrieve all published Tutorials - router.get("/published", tutorials.findAllPublished); - - // Retrieve a single Tutorial with id - router.get("/:id", tutorials.findOne); - - // Update a Tutorial with id - router.put("/:id", tutorials.update); - - // Delete a Tutorial with id - router.delete("/:id", tutorials.delete); - - // Create a new Tutorial - router.delete("/", tutorials.deleteAll); - - app.use('/api/tutorials', router); -}; diff --git a/backend/server.js b/backend/server.js index 9e913c0..f349ba7 100644 --- a/backend/server.js +++ b/backend/server.js @@ -27,7 +27,6 @@ db.mongoose }); require("./app/config/sessionJWT.config"); -require("./app/routes/tutorial.routes")(app); require("./app/routes/user.routes")(app); app.listen(port, '0.0.0.0',() => { From 5f73ec72bc4047979e20b86aff6a5634c9f24e31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Y=C3=BBki=20Vachot?= Date: Sat, 30 Oct 2021 03:10:15 +0200 Subject: [PATCH 4/5] Add playlist, video and ad skeleton --- backend/app/config/checkFormat.config.js | 9 -- backend/app/config/host.config.js | 8 ++ backend/app/config/role.config.js | 5 ++ backend/app/config/sessionJWT.config.js | 14 ++-- backend/app/controllers/ad.controller.js | 53 ++++++++++++ .../app/controllers/playlist.controller.js | 52 ++++++++++++ backend/app/controllers/user.controller.js | 83 ++++++++++--------- backend/app/controllers/video.controller.js | 60 ++++++++++++++ backend/app/models/ad.model.js | 18 ++++ backend/app/models/image.model.js | 18 ++++ backend/app/models/mongodb.model.js | 4 + backend/app/models/playlist.model.js | 16 ++++ backend/app/models/subjectTarget.model.js | 16 ++++ backend/app/models/user.model.js | 7 +- backend/app/models/video.model.js | 18 ++++ backend/app/routes/ad.routes.js | 24 ++++++ backend/app/routes/playlist.routes.js | 24 ++++++ backend/app/routes/user.routes.js | 20 ++--- backend/app/routes/video.routes.js | 27 ++++++ backend/server.js | 3 + 20 files changed, 414 insertions(+), 65 deletions(-) delete mode 100644 backend/app/config/checkFormat.config.js create mode 100644 backend/app/config/host.config.js create mode 100644 backend/app/config/role.config.js create mode 100644 backend/app/controllers/ad.controller.js create mode 100644 backend/app/controllers/playlist.controller.js create mode 100644 backend/app/controllers/video.controller.js create mode 100644 backend/app/models/ad.model.js create mode 100644 backend/app/models/image.model.js create mode 100644 backend/app/models/playlist.model.js create mode 100644 backend/app/models/subjectTarget.model.js create mode 100644 backend/app/models/video.model.js create mode 100644 backend/app/routes/ad.routes.js create mode 100644 backend/app/routes/playlist.routes.js create mode 100644 backend/app/routes/video.routes.js diff --git a/backend/app/config/checkFormat.config.js b/backend/app/config/checkFormat.config.js deleted file mode 100644 index 6b74fe0..0000000 --- a/backend/app/config/checkFormat.config.js +++ /dev/null @@ -1,9 +0,0 @@ -const {sendError} = require ("./response.config"); - -function checkFormat(req, res){ - if(req.get('Content-Type') !== 'application/json') { - return sendError(res, 401, -1, "Invalid header format (please use JSON)"); - } - return true; // Is valid -} -module.exports = checkFormat diff --git a/backend/app/config/host.config.js b/backend/app/config/host.config.js new file mode 100644 index 0000000..d743011 --- /dev/null +++ b/backend/app/config/host.config.js @@ -0,0 +1,8 @@ +module.exports = { + youtube: { + baseAPIUrl: 'https://www.youtube.com/' + }, + dailymotion: { + baseAPIUrl: 'https://api.dailymotion.com/' + } +}; diff --git a/backend/app/config/role.config.js b/backend/app/config/role.config.js new file mode 100644 index 0000000..32851a0 --- /dev/null +++ b/backend/app/config/role.config.js @@ -0,0 +1,5 @@ +module.exports = { + User: 0, + Advertiser: 5, + Admin: 10 +}; diff --git a/backend/app/config/sessionJWT.config.js b/backend/app/config/sessionJWT.config.js index b5b76cb..bca0408 100644 --- a/backend/app/config/sessionJWT.config.js +++ b/backend/app/config/sessionJWT.config.js @@ -12,9 +12,10 @@ const JWTRS256_PRIVATE_KEY = Buffer.from(process.env.JWTRS256_PRIVATE_KEY, 'base const JWTRS256_PUBLIC_KEY = Buffer.from(process.env.JWTRS256_PUBLIC_KEY, 'base64').toString('utf-8'); -function createSessionJWT (login, role) { +function createSessionJWT (id, login, role) { return sessionJWTConfig.sign( { + id: id, login: login, role: role, midExp: Math.floor(Date.now() / 1000) + 1800 @@ -29,21 +30,22 @@ function createSessionJWT (login, role) { function createSessionCookie(req, res, payload) { let jwtToken; - if (typeof payload.login !== 'undefined' && + if (typeof payload.id !== 'undefined' && + typeof payload.login !== 'undefined' && typeof payload.role !== 'undefined' && typeof payload.midExp !== 'undefined' && (Math.floor(Date.now() / 1000) <= payload.midExp)) { jwtToken = req.headers.cookie; } else { - jwtToken = createSessionJWT(payload.login, payload.role); + jwtToken = createSessionJWT(payload.id, payload.login, payload.role); } res.cookie('SESSIONID', jwtToken, {httpOnly:true, secure:false}); } function decodeSessionCookie(sessionid) { if (typeof sessionid === 'undefined') { - return {login: -1, role: -1}; + return {id: -1, login: -1, role: -1}; } try { const token = sessionJWTConfig.verify( @@ -53,7 +55,7 @@ function decodeSessionCookie(sessionid) { return {token: token}; } catch (err) { - return {login: -1, role: -1}; + return {id: -1, login: -1, role: -1}; } } @@ -83,7 +85,7 @@ function checkLogin(req, res, role=null){ if(role === null){ return token; } else{ - if(token.role !== 'undefined' && token.role === role){ + if(token.role !== 'undefined' && role.includes(token.role)){ return token; } else{ return sendError(res, 500, -1, "User doesn't have permission.", token); diff --git a/backend/app/controllers/ad.controller.js b/backend/app/controllers/ad.controller.js new file mode 100644 index 0000000..5845b33 --- /dev/null +++ b/backend/app/controllers/ad.controller.js @@ -0,0 +1,53 @@ +const db = require("../models/mongodb.model"); +const {sendError, sendMessage} = require ("../config/response.config"); +const {checkLogin} = require("../config/sessionJWT.config"); +const roles = require("../config/role.config"); +const Ads = db.ads; + +// Create a new Ad +exports.create = (req, res) => { + const token = checkLogin(req, res, [roles.Admin, roles.Advertiser]); + if(token){ + return sendError(res, 501, -1, "Ads.create not Implemented", token); + } +}; + +// Retrieve all Ads +exports.findAll = (req, res) => { + const token = checkLogin(req, res); + if(token){ + return sendError(res, 501, -1, "Ads.findAll not Implemented", token); + } +}; + +// Retrieve a single Ad with id +exports.findOne = (req, res) => { + const token = checkLogin(req, res); + if(token){ + return sendError(res, 501, -1, "Ads.findOne not Implemented", token); + } +}; + +// Update a Ad with id +exports.update = (req, res) => { + const token = checkLogin(req, res, [roles.Admin, roles.Advertiser]); + if(token){ + return sendError(res, 501, -1, "Ads.update not Implemented", token); + } +}; + +// Delete a Ad with id +exports.delete = (req, res) => { + const token = checkLogin(req, res, [roles.Admin, roles.Advertiser]); + if(token){ + return sendError(res, 501, -1, "Ads.delete not Implemented", token); + } +}; + +// Delete all Ads +exports.deleteAll = (req, res) => { + const token = checkLogin(req, res, [roles.Admin, roles.Advertiser]); + if(token){ + return sendError(res, 501, -1, "Ads.deleteAll not Implemented", token); + } +}; diff --git a/backend/app/controllers/playlist.controller.js b/backend/app/controllers/playlist.controller.js new file mode 100644 index 0000000..1b5ae3f --- /dev/null +++ b/backend/app/controllers/playlist.controller.js @@ -0,0 +1,52 @@ +const db = require("../models/mongodb.model"); +const {sendError, sendMessage} = require ("../config/response.config"); +const {checkLogin} = require("../config/sessionJWT.config"); +const Playlist = db.playlists; + +// Create a new Playlist +exports.create = (req, res) => { + const token = checkLogin(req, res); + if(token){ + return sendError(res, 501, -1, "Playlist.create not Implemented", token); + } +}; + +// Retrieve all Playlists +exports.findAll = (req, res) => { + const token = checkLogin(req, res); + if(token){ + return sendError(res, 501, -1, "Playlist.findAll not Implemented", token); + } +}; + +// Retrieve a single Playlist with id +exports.findOne = (req, res) => { + const token = checkLogin(req, res); + if(token){ + return sendError(res, 501, -1, "Playlist.findOne not Implemented", token); + } +}; + +// Update a Playlist with id +exports.update = (req, res) => { + const token = checkLogin(req, res); + if(token){ + return sendError(res, 501, -1, "Playlist.update not Implemented", token); + } +}; + +// Delete a Playlist with id +exports.delete = (req, res) => { + const token = checkLogin(req, res); + if(token){ + return sendError(res, 501, -1, "Playlist.delete not Implemented", token); + } +}; + +// Delete all Playlists +exports.deleteAll = (req, res) => { + const token = checkLogin(req, res); + if(token){ + return sendError(res, 501, -1, "Playlist.deleteAll not Implemented", token); + } +}; diff --git a/backend/app/controllers/user.controller.js b/backend/app/controllers/user.controller.js index 51a01d1..2113c7f 100644 --- a/backend/app/controllers/user.controller.js +++ b/backend/app/controllers/user.controller.js @@ -1,12 +1,11 @@ const db = require("../models/mongodb.model"); const {sendError, sendMessage} = require ("../config/response.config"); -const checkFormat = require("../config/checkFormat.config"); const {checkLogin, setSessionCookie} = require("../config/sessionJWT.config"); +const roles = require("../config/role.config"); const User = db.users; -// Authenticate an User +// Authenticate a User exports.auth = (req, res) => { - checkFormat(req, res); // Validate request if (!req.body.login || !req.body.hashPass) { sendError(res, 400,-1,"Content can not be empty ! (login and hashPass needed)"); @@ -16,10 +15,10 @@ exports.auth = (req, res) => { .findOne({login: req.body.login, hashPass: req.body.hashPass}, {role: true}) .then(data => { if (data !== null){ - setSessionCookie(req, res, { login: req.body.login, role: data.role}); + setSessionCookie(req, res, {id: data._id, login: req.body.login, role: data.role}); return sendMessage(res, 1, true); } else { - setSessionCookie(req, res, { login: -1, role: -1 }); + setSessionCookie(req, res, {id: -1, login: -1, role: -1 }); return sendError(res, 500, -1, "Invalid login or password."); } }) @@ -29,19 +28,18 @@ exports.auth = (req, res) => { } }; -// Disconnect an User +// Logout a User exports.disconnect = (req, res) => { - let token; - if(checkFormat(req, res) && (token = checkLogin(req, res))) { + const token = checkLogin(req, res); + if(token){ console.log(token); - setSessionCookie(req, res, {login: -1}); + setSessionCookie(req, res, {id: -1, login: -1, role: -1}); return sendMessage(res, 1, {message: "User disconnected"}, token); } }; // Create and Save a new User exports.create = (req, res) => { - checkFormat(req, res); // Validate request if (!req.body.login || !req.body.hashPass || !req.body.mail) { sendError(res, 400,-1,"Content can not be empty ! (login, hashPass and mail needed"); @@ -77,10 +75,10 @@ exports.create = (req, res) => { } }; -// Retrieve all Users from the database. +// Retrieve all Users from the database if admin. exports.findAll = (req, res) => { - let token; - if(checkFormat(req, res) && (token = checkLogin(req, res, 10))){ + const token = checkLogin(req, res, [roles.Admin]); + if(token){ console.log(token); const login = req.query.login; let condition = login ? { login: { $regex: new RegExp(login), $options: "i" } } : {}; @@ -95,27 +93,34 @@ exports.findAll = (req, res) => { } }; -// Find a single User with an id +// Find a single User with login if admin or login from cookie session exports.findOne = (req, res) => { - checkFormat(req, res); - const id = req.params.id; + const token = checkLogin(req, res); + if(token){ + let login; + if(token.role === [roles.Admin]){ + login = req.params.login; - User.findById(id, {hashPass: false}) - .then(data => { - if (data){ - sendMessage(res, 1, data); - } else { - sendError(res,404,-1,"Not found User with id " + id ); - } - }) - .catch(err => { - sendError(res,500,-1,err.message || "Error retrieving User with id=" + id ); - }); + } else{ + login = token.login; + } + console.log(token.role, login); + User.find({login: login}, {hashPass: false}) + .then(data => { + if (data){ + sendMessage(res, 1, data); + } else { + sendError(res,404,-1,"Not found User with login " + login ); + } + }) + .catch(err => { + sendError(res,500,-1,err.message || "Error retrieving User with login=" + login ); + }); + } }; // Update a User by the id in the request exports.update = (req, res) => { - checkFormat(req, res); if (!req.body) { sendError(res,400,-1,"Data to update can not be empty!"); } else{ @@ -137,7 +142,6 @@ exports.update = (req, res) => { // Delete a User with the specified id in the request exports.delete = (req, res) => { - checkFormat(req, res); const id = req.params.id; User.findByIdAndRemove(id) @@ -155,14 +159,17 @@ exports.delete = (req, res) => { // Delete all Users from the database. exports.deleteAll = (req, res) => { - checkFormat(req, res); - User.deleteMany({}) - .then(data => { - sendMessage(res, 1,{ - message: `${data.deletedCount} Users were deleted successfully!` + const token = checkLogin(req, res, [roles.Admin]); + if(token) { + console.log(token); + User.deleteMany({}) + .then(data => { + sendMessage(res, 1, { + message: `${data.deletedCount} Users were deleted successfully!` + }); + }) + .catch(err => { + sendError(res, 500, -1, err.message || "Some error occurred while removing all Users."); }); - }) - .catch(err => { - sendError(res,500,-1,err.message || "Some error occurred while removing all Users."); - }); + } }; diff --git a/backend/app/controllers/video.controller.js b/backend/app/controllers/video.controller.js new file mode 100644 index 0000000..4383868 --- /dev/null +++ b/backend/app/controllers/video.controller.js @@ -0,0 +1,60 @@ +const db = require("../models/mongodb.model"); +const {sendError, sendMessage} = require ("../config/response.config"); +const {checkLogin} = require("../config/sessionJWT.config"); +const Video = db.video; + +// Search Video +exports.search = (req, res) => { + const token = checkLogin(req, res); + if(token){ + return sendError(res, 501, -1, "Video.search not Implemented", token); + } +}; + +// Create a new Video +exports.create = (req, res) => { + const token = checkLogin(req, res); + if(token){ + return sendError(res, 501, -1, "Video.create not Implemented", token); + } +}; + +// Retrieve all Videos +exports.findAll = (req, res) => { + const token = checkLogin(req, res); + if(token){ + return sendError(res, 501, -1, "Video.findAll not Implemented", token); + } +}; + +// Retrieve a single Video with id +exports.findOne = (req, res) => { + const token = checkLogin(req, res); + if(token){ + return sendError(res, 501, -1, "Video.findOne not Implemented", token); + } +}; + +// Update a Video with id +exports.update = (req, res) => { + const token = checkLogin(req, res); + if(token){ + return sendError(res, 501, -1, "Video.update not Implemented", token); + } +}; + +// Delete a Video with id +exports.delete = (req, res) => { + const token = checkLogin(req, res); + if(token){ + return sendError(res, 501, -1, "Video.delete not Implemented", token); + } +}; + +// Delete all Videos +exports.deleteAll = (req, res) => { + const token = checkLogin(req, res); + if(token){ + return sendError(res, 501, -1, "Video.deleteAll not Implemented", token); + } +}; diff --git a/backend/app/models/ad.model.js b/backend/app/models/ad.model.js new file mode 100644 index 0000000..85404bc --- /dev/null +++ b/backend/app/models/ad.model.js @@ -0,0 +1,18 @@ +module.exports = mongoose => { + let schema = mongoose.Schema({ + images: [], + text: String, + subjectTarget: [], + seen: Number + }, + { timestamps: true } + ); + + schema.method("toJSON", function() { + const { __v, _id, ...object } = this.toObject(); + object.id = _id; + return object; + }); + + return mongoose.model("ad", schema); +}; diff --git a/backend/app/models/image.model.js b/backend/app/models/image.model.js new file mode 100644 index 0000000..c966167 --- /dev/null +++ b/backend/app/models/image.model.js @@ -0,0 +1,18 @@ +module.exports = mongoose => { + let schema = mongoose.Schema({ + base64: String, + fromUrl: String, + description: String, + type: Number + }, + { timestamps: true } + ); + + schema.method("toJSON", function() { + const { __v, _id, ...object } = this.toObject(); + object.id = _id; + return object; + }); + + return mongoose.model("image", schema); +}; diff --git a/backend/app/models/mongodb.model.js b/backend/app/models/mongodb.model.js index 58cce74..1fb040b 100644 --- a/backend/app/models/mongodb.model.js +++ b/backend/app/models/mongodb.model.js @@ -7,5 +7,9 @@ const db = {}; db.mongoose = mongoose; db.url = dbConfig.url; db.users = require("./user.model")(mongoose); +db.playlists = require("./playlist.model")(mongoose); +db.videos = require("./video.model")(mongoose); +db.ads = require("./ad.model")(mongoose); +db.images = require("./image.model")(mongoose); module.exports = db; diff --git a/backend/app/models/playlist.model.js b/backend/app/models/playlist.model.js new file mode 100644 index 0000000..2d7af15 --- /dev/null +++ b/backend/app/models/playlist.model.js @@ -0,0 +1,16 @@ +module.exports = mongoose => { + let schema = mongoose.Schema({ + name: String, + videos: [] + }, + { timestamps: true } + ); + + schema.method("toJSON", function() { + const { __v, _id, ...object } = this.toObject(); + object.id = _id; + return object; + }); + + return mongoose.model("playlist", schema); +}; diff --git a/backend/app/models/subjectTarget.model.js b/backend/app/models/subjectTarget.model.js new file mode 100644 index 0000000..cded850 --- /dev/null +++ b/backend/app/models/subjectTarget.model.js @@ -0,0 +1,16 @@ +module.exports = mongoose => { + let schema = mongoose.Schema({ + name: String, + keywords: [] + }, + { timestamps: true } + ); + + schema.method("toJSON", function() { + const { __v, _id, ...object } = this.toObject(); + object.id = _id; + return object; + }); + + return mongoose.model("subjectTarget", schema); +}; diff --git a/backend/app/models/user.model.js b/backend/app/models/user.model.js index c9b97b5..071c84e 100644 --- a/backend/app/models/user.model.js +++ b/backend/app/models/user.model.js @@ -1,3 +1,5 @@ +const roles = require("../config/role.config"); + module.exports = mongoose => { let schema = mongoose.Schema({ login: String, @@ -5,8 +7,9 @@ module.exports = mongoose => { mail: String, role: { type: Number, - default: 0 - } + default: roles.User + }, + playlists: [] }, { timestamps: true } ); diff --git a/backend/app/models/video.model.js b/backend/app/models/video.model.js new file mode 100644 index 0000000..ce2769e --- /dev/null +++ b/backend/app/models/video.model.js @@ -0,0 +1,18 @@ +module.exports = mongoose => { + let schema = mongoose.Schema({ + url: String, + title: String, + description: String, + views: Number + }, + { timestamps: true } + ); + + schema.method("toJSON", function() { + const { __v, _id, ...object } = this.toObject(); + object.id = _id; + return object; + }); + + return mongoose.model("video", schema); +}; diff --git a/backend/app/routes/ad.routes.js b/backend/app/routes/ad.routes.js new file mode 100644 index 0000000..943dcc7 --- /dev/null +++ b/backend/app/routes/ad.routes.js @@ -0,0 +1,24 @@ +const ads = require("../controllers/ad.controller"); +module.exports = app => { + let router = require("express").Router(); + + // Create a new Ad + router.post("/user/ad", ads.create); + + // Retrieve all Ads + router.get("/user/ad", ads.findAll); + + // Retrieve a single Ad with id + router.get("/user/ad/:id", ads.findOne); + + // Update an Ad with id + router.put("/user/ad/:id", ads.update); + + // Delete an Ad with id + router.delete("/user/ad/:id", ads.delete); + + // Delete all Ads + router.delete("/user/ad", ads.deleteAll); + + app.use('/api', router); +}; diff --git a/backend/app/routes/playlist.routes.js b/backend/app/routes/playlist.routes.js new file mode 100644 index 0000000..1d8241a --- /dev/null +++ b/backend/app/routes/playlist.routes.js @@ -0,0 +1,24 @@ +const playlists = require("../controllers/playlist.controller"); +module.exports = app => { + let router = require("express").Router(); + + // Create a new Playlist + router.post("/user/playlist", playlists.create); + + // Retrieve all Playlists + router.get("/user/playlists", playlists.findAll); + + // Retrieve a single Playlist with id + router.get("/user/playlist/:id", playlists.findOne); + + // Update a Playlist with id + router.put("/user/playlist/:id", playlists.update); + + // Delete a Playlist with id + router.delete("/user/playlist/:id", playlists.delete); + + // Delete all Playlists + router.delete("/user/playlists", playlists.deleteAll); + + app.use('/api', router); +}; diff --git a/backend/app/routes/user.routes.js b/backend/app/routes/user.routes.js index b3ba76f..5e30e34 100644 --- a/backend/app/routes/user.routes.js +++ b/backend/app/routes/user.routes.js @@ -3,28 +3,28 @@ module.exports = app => { let router = require("express").Router(); // Create a new User - router.post("/", users.create); + router.post("/user", users.create); // Retrieve all Users - router.get("/", users.findAll); + router.get("/users", users.findAll); // Retrieve a single User with id - router.get("/:id", users.findOne); + router.get("/user/:id", users.findOne); // Update a User with id - router.put("/:id", users.update); + router.put("/user/:id", users.update); // Delete a User with id - router.delete("/:id", users.delete); + router.delete("/user/:id", users.delete); // Delete all Users - router.delete("/", users.deleteAll); + router.delete("/users", users.deleteAll); // Authenticate a User - router.post("/auth", users.auth); + router.post("/user/auth", users.auth); - // Disconnect a User - router.delete("/auth/disconnect", users.disconnect); + // Logout a User + router.delete("/user/logout", users.disconnect); - app.use('/api/users', router); + app.use('/api', router); }; diff --git a/backend/app/routes/video.routes.js b/backend/app/routes/video.routes.js new file mode 100644 index 0000000..42af7f4 --- /dev/null +++ b/backend/app/routes/video.routes.js @@ -0,0 +1,27 @@ +const videos = require("../controllers/video.controller"); +module.exports = app => { + let router = require("express").Router(); + + // Search Video + router.post("/videos", videos.search); + + // Create a new Video + router.post("/video", videos.create); + + // Retrieve all Videos + router.get("/videos", videos.findAll); + + // Retrieve a single Video with id + router.get("/video/:id", videos.findOne); + + // Update a Video with id + router.put("/video/:id", videos.update); + + // Delete a Video with id + router.delete("/video/:id", videos.delete); + + // Delete all Videos + router.delete("/videos", videos.deleteAll); + + app.use('/api', router); +}; diff --git a/backend/server.js b/backend/server.js index f349ba7..73f2ff2 100644 --- a/backend/server.js +++ b/backend/server.js @@ -28,6 +28,9 @@ db.mongoose require("./app/config/sessionJWT.config"); require("./app/routes/user.routes")(app); +require("./app/routes/playlist.routes")(app); +require("./app/routes/video.routes")(app); +require("./app/routes/ad.routes")(app); app.listen(port, '0.0.0.0',() => { console.log (`listening on port ${port}`); From 76515d3297f0530739106dd51968870cf5f1c2aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Y=C3=BBki=20Vachot?= Date: Sat, 30 Oct 2021 03:13:12 +0200 Subject: [PATCH 5/5] remove require test of sessionJWT --- backend/server.js | 1 - 1 file changed, 1 deletion(-) diff --git a/backend/server.js b/backend/server.js index 73f2ff2..de1b5f4 100644 --- a/backend/server.js +++ b/backend/server.js @@ -26,7 +26,6 @@ db.mongoose } }); -require("./app/config/sessionJWT.config"); require("./app/routes/user.routes")(app); require("./app/routes/playlist.routes")(app); require("./app/routes/video.routes")(app);