├── .env.example ├── .gitignore ├── CHANGELOG.md ├── app.js ├── app ├── controlles │ ├── auth.js │ ├── hotels.js │ └── users.js ├── helpers │ ├── generateToken.js │ ├── handleBcrypt.js │ ├── handleError.js │ └── validateHelper.js ├── middleware │ ├── auth.js │ ├── cache.js │ ├── origin.js │ └── roleAuth.js ├── models │ ├── hotels.js │ └── users.js ├── routes │ ├── auth.js │ ├── hotels.js │ ├── index.js │ └── users.js └── validators │ └── users.js ├── config ├── jwtConfig.js └── mongo.js ├── package-lock.json └── package.json /.env.example: -------------------------------------------------------------------------------- 1 | DB_URI= 2 | PORT= 3 | JWT_SECRET= -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .env -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## 🤔 Dudas? 2 | 3 | ```sequence 4 | Usuario->API: Usuario relaliza petición 🤦‍♂️🤦‍♂️ 5 | Note right of API: Api revisa si tiene cache 6 | API-->Usuario: Buenas noticias respondemos 🐱‍🏍 7 | ``` 8 | 9 | ##### ¿Que metodo de peticion se recomienda cachear? 10 | >GET 11 | 12 | ##### ¿Puedo cambiar el tiempo de cache a mi gusto? 13 | > SI puedes establecer minutos o milisegundos 14 | 15 | ##### ¿Puedo controlar el tiempo de cache dependiendo de statusCode 200, 404, 500? 16 | > Si 17 | 18 | #### ¿Puedo conectar con Redis? 19 | > Si 20 | ```js 21 | engine: require('expeditious-engine-redis')( 22 | { 23 | host: '127.0.0.2', 24 | port: 6379 25 | } 26 | ) 27 | ``` 28 | 29 | ##### ¿Cuando se debe usar? 30 | > Lo recomiendo para consultas repetitivas y comportamiento predecible 31 | -------------------------------------------------------------------------------- /app.js: -------------------------------------------------------------------------------- 1 | require('dotenv').config() 2 | const epxress = require('express') 3 | const cors = require('cors') 4 | const app = epxress() 5 | const { dbConnect } = require('./config/mongo') 6 | 7 | const PORT = process.env.PORT || 3000 8 | app.use(cors()) 9 | app.use(epxress.json()) 10 | 11 | app.use('/api/1.0', require('./app/routes')) 12 | 13 | dbConnect() 14 | app.listen(PORT, () => { 15 | console.log('API lista por el puerto ', PORT) 16 | }) -------------------------------------------------------------------------------- /app/controlles/auth.js: -------------------------------------------------------------------------------- 1 | const { httpError } = require('../helpers/handleError') 2 | const { encrypt, compare } = require('../helpers/handleBcrypt') 3 | const { tokenSign } = require('../helpers/generateToken') 4 | const userModel = require('../models/users') 5 | 6 | //TODO: Login! 7 | const loginCtrl = async (req, res) => { 8 | try { 9 | const { email, password } = req.body 10 | 11 | const user = await userModel.findOne({ email }) 12 | 13 | if (!user) { 14 | res.status(404) 15 | res.send({ error: 'User not found' }) 16 | } 17 | 18 | const checkPassword = await compare(password, user.password) //TODO: Contraseña! 19 | 20 | //TODO JWT 👉 21 | const tokenSession = await tokenSign(user) //TODO: 2d2d2d2d2d2d2 22 | 23 | if (checkPassword) { //TODO Contraseña es correcta! 24 | res.send({ 25 | data: user, 26 | tokenSession 27 | }) 28 | return 29 | } 30 | 31 | if (!checkPassword) { 32 | res.status(409) 33 | res.send({ 34 | error: 'Invalid password' 35 | }) 36 | return 37 | } 38 | 39 | } catch (e) { 40 | httpError(res, e) 41 | } 42 | } 43 | 44 | //TODO: Registramos usuario! 45 | const registerCtrl = async (req, res) => { 46 | try { 47 | //TODO: Datos que envias desde el front (postman) 48 | const { email, password, name } = req.body 49 | 50 | const passwordHash = await encrypt(password) //TODO: (123456)<--- Encriptando!! 51 | const registerUser = await userModel.create({ 52 | email, 53 | name, 54 | password: passwordHash 55 | }) 56 | 57 | res.send({ data: registerUser }) 58 | 59 | } catch (e) { 60 | httpError(res, e) 61 | } 62 | } 63 | 64 | 65 | 66 | module.exports = { loginCtrl, registerCtrl } -------------------------------------------------------------------------------- /app/controlles/hotels.js: -------------------------------------------------------------------------------- 1 | const { httpError } = require('../helpers/handleError') 2 | const hotelModel = require('../models/hotels') 3 | 4 | const getItems = async (req, res) => { 5 | try { 6 | const listAll = await hotelModel.find({}) 7 | 8 | //TODO: Simular delay 2 segundos 9 | 10 | setTimeout(() => { 11 | res.send({ data: listAll }) 12 | }, 3000) 13 | 14 | 15 | } catch (e) { 16 | httpError(res, e) 17 | } 18 | } 19 | 20 | const getItem = (req, res) => { 21 | 22 | } 23 | 24 | const createItem = async (req, res) => { 25 | try { 26 | const { name, price, room } = req.body 27 | const resDetail = await hotelModel.create({ 28 | name, price, room 29 | }) 30 | res.send({ data: resDetail }) 31 | } catch (e) { 32 | httpError(res, e) 33 | } 34 | } 35 | 36 | 37 | const updateItem = (req, res) => { 38 | 39 | } 40 | 41 | const deleteItem = (req, res) => { 42 | 43 | } 44 | 45 | module.exports = { getItem, getItems, deleteItem, createItem, updateItem } -------------------------------------------------------------------------------- /app/controlles/users.js: -------------------------------------------------------------------------------- 1 | const { httpError } = require('../helpers/handleError') 2 | const userModel = require('../models/users') 3 | 4 | const getItems = async (req, res) => { 5 | try { 6 | const listAll = await userModel.find({}) 7 | res.send({ data: listAll }) 8 | } catch (e) { 9 | httpError(res, e) 10 | } 11 | } 12 | 13 | const getItem = (req, res) => { 14 | 15 | } 16 | 17 | const createItem = async (req, res) => { 18 | try { 19 | const { name, age, email } = req.body 20 | const resDetail = await userModel.create({ 21 | name, age, email 22 | }) 23 | res.send({ data: resDetail }) 24 | } catch (e) { 25 | httpError(res, e) 26 | } 27 | } 28 | 29 | 30 | const updateItem = (req, res) => { 31 | 32 | } 33 | 34 | const deleteItem = (req, res) => { 35 | 36 | } 37 | 38 | module.exports = { getItem, getItems, deleteItem, createItem, updateItem } -------------------------------------------------------------------------------- /app/helpers/generateToken.js: -------------------------------------------------------------------------------- 1 | const jwt = require('jsonwebtoken') //TODO : 😎 2 | 3 | const tokenSign = async (user) => { //TODO: Genera Token 4 | return jwt.sign( 5 | { 6 | _id: user._id, //TODO: <--- 7 | role: user.role 8 | }, //TODO: Payload ! Carga útil 9 | process.env.JWT_SECRET, //TODO ENV 10 | { 11 | expiresIn: "2h", //TODO tiempo de vida 12 | } 13 | ); 14 | } 15 | 16 | const verifyToken = async (token) => { 17 | try { 18 | return jwt.verify(token, process.env.JWT_SECRET) 19 | } catch (e) { 20 | return null 21 | } 22 | } 23 | 24 | const decodeSign = (token) => { //TODO: Verificar que el token sea valido y correcto 25 | return jwt.decode(token, null) 26 | } 27 | 28 | 29 | 30 | module.exports = { tokenSign, decodeSign, verifyToken } -------------------------------------------------------------------------------- /app/helpers/handleBcrypt.js: -------------------------------------------------------------------------------- 1 | const bcrypt = require('bcryptjs') //TODO: <--- 😎 2 | 3 | //TODO: Encriptamos!! 4 | const encrypt = async (textPlain) => { //TODO: 123456 5 | const hash = await bcrypt.hash(textPlain, 10) //0404o4ofoto4o 6 | return hash 7 | } 8 | 9 | //TODO: Comparamos!! 10 | const compare = async (passwordPlain, hashPassword) => { 11 | return await bcrypt.compare(passwordPlain, hashPassword) 12 | } 13 | 14 | module.exports = { encrypt, compare } -------------------------------------------------------------------------------- /app/helpers/handleError.js: -------------------------------------------------------------------------------- 1 | const httpError = (res, err) => { 2 | console.log(err) 3 | res.status(500) 4 | res.send({ error: 'Algo ocurrio' }) 5 | } 6 | 7 | module.exports = { httpError } -------------------------------------------------------------------------------- /app/helpers/validateHelper.js: -------------------------------------------------------------------------------- 1 | const { validationResult } = require('express-validator'); //TODO: 2 | 3 | const validateResult = (req, res, next) => { 4 | try { 5 | validationResult(req).throw() 6 | return next() 7 | } catch (err) { 8 | res.status(403) 9 | res.send({ errors: err.array() }) 10 | } 11 | } 12 | 13 | module.exports = { validateResult } -------------------------------------------------------------------------------- /app/middleware/auth.js: -------------------------------------------------------------------------------- 1 | 2 | const { verifyToken } = require('../helpers/generateToken') 3 | 4 | const checkAuth = async (req, res, next) => { 5 | try { 6 | //TODO: authorization: Bearer 1010101010101001010100 7 | const token = req.headers.authorization.split(' ').pop() //TODO:123123213 8 | const tokenData = await verifyToken(token) 9 | if (tokenData._id) { 10 | next() 11 | } else { 12 | res.status(409) 13 | res.send({ error: 'Tu por aqui no pasas!' }) 14 | } 15 | 16 | } catch (e) { 17 | console.log(e) 18 | res.status(409) 19 | res.send({ error: 'Tu por aqui no pasas!' }) 20 | } 21 | 22 | } 23 | 24 | module.exports = checkAuth -------------------------------------------------------------------------------- /app/middleware/cache.js: -------------------------------------------------------------------------------- 1 | const getExpeditiousCache = require('express-expeditious'); 2 | 3 | const defaultOptions = { 4 | namespace: 'expresscache', 5 | defaultTtl: '15 minute', //TODO: 60 * 1000 6 | statusCodeExpires: { 7 | 404: '5 minutes', 8 | 500: 0 // 1 minute in milliseconds 9 | } 10 | } 11 | 12 | const cacheInit = getExpeditiousCache(defaultOptions) 13 | 14 | module.exports = { cacheInit } 15 | -------------------------------------------------------------------------------- /app/middleware/origin.js: -------------------------------------------------------------------------------- 1 | 2 | const checkOrigin = (req, res, next) => { 3 | try { 4 | const token = req.headers.authorization.split(' ').pop() 5 | if (token === '123456') { 6 | next() 7 | } else { 8 | res.status(409) 9 | res.send({ error: 'Tu por aqui no pasas!' }) 10 | } 11 | 12 | } catch (e) { 13 | next() 14 | } 15 | 16 | } 17 | 18 | module.exports = checkOrigin -------------------------------------------------------------------------------- /app/middleware/roleAuth.js: -------------------------------------------------------------------------------- 1 | 2 | const { verifyToken } = require('../helpers/generateToken') 3 | const userModel = require('../models/users') 4 | 5 | const checkRoleAuth = (roles) => async (req, res, next) => { 6 | try { 7 | const token = req.headers.authorization.split(' ').pop() //TODO: 231231321 8 | const tokenData = await verifyToken(token) 9 | const userData = await userModel.findById(tokenData._id) //TODO: 696966 10 | 11 | //TODO ['user'].includes('user') 12 | if ([].concat(roles).includes(userData.role)) { //TODO: 13 | next() 14 | } else { 15 | res.status(409) 16 | res.send({ error: 'No tienes permisos' }) 17 | } 18 | 19 | } catch (e) { 20 | console.log(e) 21 | res.status(409) 22 | res.send({ error: 'Tu por aqui no pasas!' }) 23 | } 24 | 25 | } 26 | 27 | module.exports = checkRoleAuth -------------------------------------------------------------------------------- /app/models/hotels.js: -------------------------------------------------------------------------------- 1 | const mongoose = require('mongoose') 2 | 3 | const HotelScheme = new mongoose.Schema({ 4 | name: { 5 | type: String 6 | }, 7 | price: { 8 | type: Number 9 | }, 10 | rooms: { 11 | type: Number 12 | } 13 | }, 14 | { 15 | timestamps: true, 16 | versionKey: false 17 | }) 18 | 19 | module.exports = mongoose.model('hotels', HotelScheme) -------------------------------------------------------------------------------- /app/models/users.js: -------------------------------------------------------------------------------- 1 | const mongoose = require('mongoose') 2 | 3 | const UserScheme = new mongoose.Schema({ 4 | name: { 5 | type: String 6 | }, 7 | age: { 8 | type: Number 9 | }, 10 | email: { 11 | type: String 12 | }, 13 | 14 | password: { 15 | type: String 16 | }, 17 | role: { 18 | type: String, 19 | default: 'user' 20 | } 21 | }, 22 | { 23 | timestamps: true, 24 | versionKey: false 25 | }) 26 | 27 | module.exports = mongoose.model('users', UserScheme) -------------------------------------------------------------------------------- /app/routes/auth.js: -------------------------------------------------------------------------------- 1 | const express = require('express') 2 | const router = express.Router() 3 | 4 | const { loginCtrl, registerCtrl } = require('../controlles/auth') 5 | 6 | //TODO: Login ! 7 | router.post('/login', loginCtrl) 8 | 9 | 10 | //TODO: Registrar un usuario 11 | router.post('/register', registerCtrl) 12 | 13 | 14 | module.exports = router -------------------------------------------------------------------------------- /app/routes/hotels.js: -------------------------------------------------------------------------------- 1 | const express = require('express') 2 | const router = express.Router() 3 | const checkOrigin = require('../middleware/origin') 4 | const { cacheInit } = require('../middleware/cache') 5 | const { getItems, getItem, createItem, deleteItem, updateItem } = require('../controlles/hotels') 6 | 7 | //TODO: Turbo 🐱‍🏍 cache! 8 | router.get( 9 | '/', 10 | checkOrigin, 11 | cacheInit, //TODO: <--- 😨 ¿WTF? 12 | getItems 13 | ) 14 | 15 | router.get('/:id', checkOrigin, getItem) 16 | 17 | router.post('/', checkOrigin, cacheInit, createItem) 18 | 19 | router.patch('/:id', updateItem) 20 | 21 | router.delete('/:id', deleteItem) 22 | 23 | 24 | module.exports = router -------------------------------------------------------------------------------- /app/routes/index.js: -------------------------------------------------------------------------------- 1 | const epxress = require('express') 2 | const router = epxress.Router() 3 | const fs = require('fs') 4 | 5 | const pathRouter = `${__dirname}` 6 | 7 | const removeExtension = (fileName) => { 8 | return fileName.split('.').shift() 9 | } 10 | 11 | fs.readdirSync(pathRouter).filter((file) => { 12 | const fileWithOutExt = removeExtension(file) 13 | const skip = ['index'].includes(fileWithOutExt) 14 | if (!skip) { 15 | router.use(`/${fileWithOutExt}`, require(`./${fileWithOutExt}`)) //TODO: localhost/users 16 | console.log('CARGAR RUTA ---->', fileWithOutExt) 17 | } 18 | }) 19 | 20 | router.get('*', (req, res) => { 21 | res.status(404) 22 | res.send({ error: 'Not found' }) 23 | }) 24 | 25 | module.exports = router -------------------------------------------------------------------------------- /app/routes/users.js: -------------------------------------------------------------------------------- 1 | const express = require('express') 2 | const router = express.Router() 3 | const checkOrigin = require('../middleware/origin') 4 | const checkAuth = require('../middleware/auth') 5 | const checkRoleAuth = require('../middleware/roleAuth') 6 | const { getItems, getItem, createItem, deleteItem, updateItem } = require('../controlles/users') 7 | const { validateCreate } = require('../validators/users') 8 | 9 | router.get('/', checkAuth, checkRoleAuth(['admin']), getItems) 10 | 11 | router.get('/:id', checkOrigin, getItem) 12 | 13 | //TODO: Donde recibimos data 14 | router.post('/', checkOrigin, validateCreate, createItem) 15 | 16 | router.patch('/:id', updateItem) 17 | 18 | router.delete('/:id', deleteItem) 19 | 20 | 21 | module.exports = router -------------------------------------------------------------------------------- /app/validators/users.js: -------------------------------------------------------------------------------- 1 | const { check } = require('express-validator') //TODO <--- 2 | const { validateResult } = require('../helpers/validateHelper') 3 | 4 | const validateCreate = [ //TODO:name, age, email 5 | check('name') 6 | .exists() 7 | .not() 8 | .isLength({ min: 5 }) 9 | .isEmpty(), 10 | check('age') 11 | .exists() 12 | .isNumeric() 13 | .custom((value, { req }) => { 14 | //TODO: 18 15 | if (value < 18 || value > 40) { 16 | throw new Error('Rango de edad debe ser entre 18 y 40') 17 | } 18 | return true 19 | }) 20 | , 21 | check('email') 22 | .exists() 23 | .isEmail(), 24 | (req, res, next) => { 25 | validateResult(req, res, next) 26 | } 27 | ] 28 | 29 | module.exports = { validateCreate } -------------------------------------------------------------------------------- /config/jwtConfig.js: -------------------------------------------------------------------------------- 1 | const jsonwebtoken = require('jsonwebtoken') -------------------------------------------------------------------------------- /config/mongo.js: -------------------------------------------------------------------------------- 1 | const mongoose = require('mongoose') 2 | 3 | const dbConnect = () => { 4 | const DB_URI = process.env.DB_URI 5 | mongoose.connect(DB_URI, { 6 | useNewUrlParser: true, 7 | useUnifiedTopology: true 8 | }, (err, res) => { 9 | if (!err) { 10 | console.log('**** CONEXION CORRECTA ****') 11 | } else { 12 | console.log('***** ERROR DE CONEXION ****') 13 | } 14 | }) 15 | } 16 | 17 | module.exports = { dbConnect } -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "node-seed-api", 3 | "version": "1.0.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "@types/bson": { 8 | "version": "4.0.4", 9 | "resolved": "https://registry.npmjs.org/@types/bson/-/bson-4.0.4.tgz", 10 | "integrity": "sha512-awqorHvQS0DqxkHQ/FxcPX9E+H7Du51Qw/2F+5TBMSaE3G0hm+8D3eXJ6MAzFw75nE8V7xF0QvzUSdxIjJb/GA==", 11 | "requires": { 12 | "@types/node": "*" 13 | } 14 | }, 15 | "@types/mongodb": { 16 | "version": "3.6.20", 17 | "resolved": "https://registry.npmjs.org/@types/mongodb/-/mongodb-3.6.20.tgz", 18 | "integrity": "sha512-WcdpPJCakFzcWWD9juKoZbRtQxKIMYF/JIAM4JrNHrMcnJL6/a2NWjXxW7fo9hxboxxkg+icff8d7+WIEvKgYQ==", 19 | "requires": { 20 | "@types/bson": "*", 21 | "@types/node": "*" 22 | } 23 | }, 24 | "@types/node": { 25 | "version": "15.14.2", 26 | "resolved": "https://registry.npmjs.org/@types/node/-/node-15.14.2.tgz", 27 | "integrity": "sha512-dvMUE/m2LbXPwlvVuzCyslTEtQ2ZwuuFClDrOQ6mp2CenCg971719PTILZ4I6bTP27xfFFc+o7x2TkLuun/MPw==" 28 | }, 29 | "accepts": { 30 | "version": "1.3.7", 31 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", 32 | "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", 33 | "requires": { 34 | "mime-types": "~2.1.24", 35 | "negotiator": "0.6.2" 36 | } 37 | }, 38 | "array-flatten": { 39 | "version": "1.1.1", 40 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", 41 | "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" 42 | }, 43 | "assert-plus": { 44 | "version": "1.0.0", 45 | "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", 46 | "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" 47 | }, 48 | "async": { 49 | "version": "2.0.1", 50 | "resolved": "https://registry.npmjs.org/async/-/async-2.0.1.tgz", 51 | "integrity": "sha1-twnMAoCpw28J9FNr6CPIOKkEniU=", 52 | "requires": { 53 | "lodash": "^4.8.0" 54 | } 55 | }, 56 | "bcryptjs": { 57 | "version": "2.4.3", 58 | "resolved": "https://registry.npmjs.org/bcryptjs/-/bcryptjs-2.4.3.tgz", 59 | "integrity": "sha1-mrVie5PmBiH/fNrF2pczAn3x0Ms=" 60 | }, 61 | "bl": { 62 | "version": "2.2.1", 63 | "resolved": "https://registry.npmjs.org/bl/-/bl-2.2.1.tgz", 64 | "integrity": "sha512-6Pesp1w0DEX1N550i/uGV/TqucVL4AM/pgThFSN/Qq9si1/DF9aIHs1BxD8V/QU0HoeHO6cQRTAuYnLPKq1e4g==", 65 | "requires": { 66 | "readable-stream": "^2.3.5", 67 | "safe-buffer": "^5.1.1" 68 | } 69 | }, 70 | "bluebird": { 71 | "version": "3.5.1", 72 | "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz", 73 | "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==" 74 | }, 75 | "body-parser": { 76 | "version": "1.19.0", 77 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", 78 | "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", 79 | "requires": { 80 | "bytes": "3.1.0", 81 | "content-type": "~1.0.4", 82 | "debug": "2.6.9", 83 | "depd": "~1.1.2", 84 | "http-errors": "1.7.2", 85 | "iconv-lite": "0.4.24", 86 | "on-finished": "~2.3.0", 87 | "qs": "6.7.0", 88 | "raw-body": "2.4.0", 89 | "type-is": "~1.6.17" 90 | } 91 | }, 92 | "bson": { 93 | "version": "1.1.6", 94 | "resolved": "https://registry.npmjs.org/bson/-/bson-1.1.6.tgz", 95 | "integrity": "sha512-EvVNVeGo4tHxwi8L6bPj3y3itEvStdwvvlojVxxbyYfoaxJ6keLgrTuKdyfEAszFK+H3olzBuafE0yoh0D1gdg==" 96 | }, 97 | "buffer-equal-constant-time": { 98 | "version": "1.0.1", 99 | "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", 100 | "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=" 101 | }, 102 | "bytes": { 103 | "version": "3.1.0", 104 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", 105 | "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" 106 | }, 107 | "content-disposition": { 108 | "version": "0.5.3", 109 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", 110 | "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", 111 | "requires": { 112 | "safe-buffer": "5.1.2" 113 | } 114 | }, 115 | "content-type": { 116 | "version": "1.0.4", 117 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", 118 | "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" 119 | }, 120 | "cookie": { 121 | "version": "0.4.0", 122 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", 123 | "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==" 124 | }, 125 | "cookie-signature": { 126 | "version": "1.0.6", 127 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", 128 | "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" 129 | }, 130 | "core-util-is": { 131 | "version": "1.0.2", 132 | "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", 133 | "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" 134 | }, 135 | "cors": { 136 | "version": "2.8.5", 137 | "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", 138 | "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", 139 | "requires": { 140 | "object-assign": "^4", 141 | "vary": "^1" 142 | } 143 | }, 144 | "debug": { 145 | "version": "2.6.9", 146 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 147 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 148 | "requires": { 149 | "ms": "2.0.0" 150 | } 151 | }, 152 | "denque": { 153 | "version": "1.5.0", 154 | "resolved": "https://registry.npmjs.org/denque/-/denque-1.5.0.tgz", 155 | "integrity": "sha512-CYiCSgIF1p6EUByQPlGkKnP1M9g0ZV3qMIrqMqZqdwazygIA/YP2vrbcyl1h/WppKJTdl1F85cXIle+394iDAQ==" 156 | }, 157 | "depd": { 158 | "version": "1.1.2", 159 | "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", 160 | "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" 161 | }, 162 | "destroy": { 163 | "version": "1.0.4", 164 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", 165 | "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" 166 | }, 167 | "dotenv": { 168 | "version": "10.0.0", 169 | "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz", 170 | "integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==" 171 | }, 172 | "double-ended-queue": { 173 | "version": "2.1.0-0", 174 | "resolved": "https://registry.npmjs.org/double-ended-queue/-/double-ended-queue-2.1.0-0.tgz", 175 | "integrity": "sha1-ED01J/0xUo9AGIEwyEHv3XgmTlw=" 176 | }, 177 | "ecdsa-sig-formatter": { 178 | "version": "1.0.11", 179 | "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", 180 | "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", 181 | "requires": { 182 | "safe-buffer": "^5.0.1" 183 | } 184 | }, 185 | "ee-first": { 186 | "version": "1.1.1", 187 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", 188 | "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" 189 | }, 190 | "encodeurl": { 191 | "version": "1.0.2", 192 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", 193 | "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" 194 | }, 195 | "escape-html": { 196 | "version": "1.0.3", 197 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", 198 | "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" 199 | }, 200 | "etag": { 201 | "version": "1.8.1", 202 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", 203 | "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" 204 | }, 205 | "expeditious": { 206 | "version": "1.0.1", 207 | "resolved": "https://registry.npmjs.org/expeditious/-/expeditious-1.0.1.tgz", 208 | "integrity": "sha1-mVt6x2dBpmApiRRJ1YZ7zMM4sw8=", 209 | "requires": { 210 | "debug": "~2.6.9", 211 | "safejson": "~1.0.1", 212 | "verror": "~1.6.1" 213 | }, 214 | "dependencies": { 215 | "verror": { 216 | "version": "1.6.1", 217 | "resolved": "https://registry.npmjs.org/verror/-/verror-1.6.1.tgz", 218 | "integrity": "sha1-I2QCBgZIwhnRFiwkUdHDQaDhyc4=", 219 | "requires": { 220 | "core-util-is": "1.0.2", 221 | "extsprintf": "1.2.0" 222 | } 223 | } 224 | } 225 | }, 226 | "expeditious-engine-memory": { 227 | "version": "0.2.1", 228 | "resolved": "https://registry.npmjs.org/expeditious-engine-memory/-/expeditious-engine-memory-0.2.1.tgz", 229 | "integrity": "sha1-zh2cvfLfmn25HNkZE8KLpTeWXRE=", 230 | "requires": { 231 | "expeditious": "~1.0.0" 232 | } 233 | }, 234 | "expeditious-engine-redis": { 235 | "version": "0.1.2", 236 | "resolved": "https://registry.npmjs.org/expeditious-engine-redis/-/expeditious-engine-redis-0.1.2.tgz", 237 | "integrity": "sha512-qYC3PZ+6oSQbgGXCUOg5D4mbqQrLoxfMR90HAicDtCwTm27Dc+9yVuxWeKqVUpNjpTHyNWw+Z7E+/enIDjuOfQ==", 238 | "requires": { 239 | "async": "~2.0.0", 240 | "expeditious": "~0.1.0", 241 | "redis": "~2.6.2", 242 | "verror": "~1.9.0" 243 | }, 244 | "dependencies": { 245 | "expeditious": { 246 | "version": "0.1.0", 247 | "resolved": "https://registry.npmjs.org/expeditious/-/expeditious-0.1.0.tgz", 248 | "integrity": "sha1-vm9vkSJQbW3ME3ZYx2hGQJtG/zQ=", 249 | "requires": { 250 | "safejson": "^1.0.1", 251 | "verror": "^1.6.1" 252 | } 253 | }, 254 | "verror": { 255 | "version": "1.9.0", 256 | "resolved": "https://registry.npmjs.org/verror/-/verror-1.9.0.tgz", 257 | "integrity": "sha1-EHqKLRTDNYb8S7gwBXzS0Zripu4=", 258 | "requires": { 259 | "assert-plus": "^1.0.0", 260 | "core-util-is": "1.0.2", 261 | "extsprintf": "^1.2.0" 262 | } 263 | } 264 | } 265 | }, 266 | "express": { 267 | "version": "4.17.1", 268 | "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", 269 | "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", 270 | "requires": { 271 | "accepts": "~1.3.7", 272 | "array-flatten": "1.1.1", 273 | "body-parser": "1.19.0", 274 | "content-disposition": "0.5.3", 275 | "content-type": "~1.0.4", 276 | "cookie": "0.4.0", 277 | "cookie-signature": "1.0.6", 278 | "debug": "2.6.9", 279 | "depd": "~1.1.2", 280 | "encodeurl": "~1.0.2", 281 | "escape-html": "~1.0.3", 282 | "etag": "~1.8.1", 283 | "finalhandler": "~1.1.2", 284 | "fresh": "0.5.2", 285 | "merge-descriptors": "1.0.1", 286 | "methods": "~1.1.2", 287 | "on-finished": "~2.3.0", 288 | "parseurl": "~1.3.3", 289 | "path-to-regexp": "0.1.7", 290 | "proxy-addr": "~2.0.5", 291 | "qs": "6.7.0", 292 | "range-parser": "~1.2.1", 293 | "safe-buffer": "5.1.2", 294 | "send": "0.17.1", 295 | "serve-static": "1.14.1", 296 | "setprototypeof": "1.1.1", 297 | "statuses": "~1.5.0", 298 | "type-is": "~1.6.18", 299 | "utils-merge": "1.0.1", 300 | "vary": "~1.1.2" 301 | } 302 | }, 303 | "express-expeditious": { 304 | "version": "5.1.1", 305 | "resolved": "https://registry.npmjs.org/express-expeditious/-/express-expeditious-5.1.1.tgz", 306 | "integrity": "sha512-4akMwHm8TVRYzm/HQ520fJxqT1NIEb0J+CNzJ18l1kXt0GSnIHsRt2WpoI+8jdD/g3tf/Ggz+vbW6rwronJdvA==", 307 | "requires": { 308 | "debug": "~4.1.0", 309 | "expeditious": "~1.0.1", 310 | "expeditious-engine-memory": "~0.2.0", 311 | "on-finished": "~2.3.0", 312 | "timestring": "~5.0.0", 313 | "verror": "~1.10.0" 314 | }, 315 | "dependencies": { 316 | "debug": { 317 | "version": "4.1.1", 318 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", 319 | "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", 320 | "requires": { 321 | "ms": "^2.1.1" 322 | } 323 | }, 324 | "ms": { 325 | "version": "2.1.3", 326 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", 327 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" 328 | } 329 | } 330 | }, 331 | "express-validator": { 332 | "version": "6.12.1", 333 | "resolved": "https://registry.npmjs.org/express-validator/-/express-validator-6.12.1.tgz", 334 | "integrity": "sha512-olpTAv0ZB5IhNuDQ2rodKAuJsewgFgLIsczJMAWD6T0Yvxsa+j/Hk61jl8e26lAq+oJr6hUqPRjdlOBKhFlWeQ==", 335 | "requires": { 336 | "lodash": "^4.17.21", 337 | "validator": "^13.5.2" 338 | } 339 | }, 340 | "extsprintf": { 341 | "version": "1.2.0", 342 | "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.2.0.tgz", 343 | "integrity": "sha1-WtlGwi9bMrp/jNdCZxHG6KP8JSk=" 344 | }, 345 | "finalhandler": { 346 | "version": "1.1.2", 347 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", 348 | "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", 349 | "requires": { 350 | "debug": "2.6.9", 351 | "encodeurl": "~1.0.2", 352 | "escape-html": "~1.0.3", 353 | "on-finished": "~2.3.0", 354 | "parseurl": "~1.3.3", 355 | "statuses": "~1.5.0", 356 | "unpipe": "~1.0.0" 357 | } 358 | }, 359 | "forwarded": { 360 | "version": "0.2.0", 361 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", 362 | "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==" 363 | }, 364 | "fresh": { 365 | "version": "0.5.2", 366 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", 367 | "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" 368 | }, 369 | "http-errors": { 370 | "version": "1.7.2", 371 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", 372 | "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", 373 | "requires": { 374 | "depd": "~1.1.2", 375 | "inherits": "2.0.3", 376 | "setprototypeof": "1.1.1", 377 | "statuses": ">= 1.5.0 < 2", 378 | "toidentifier": "1.0.0" 379 | } 380 | }, 381 | "iconv-lite": { 382 | "version": "0.4.24", 383 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", 384 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", 385 | "requires": { 386 | "safer-buffer": ">= 2.1.2 < 3" 387 | } 388 | }, 389 | "inherits": { 390 | "version": "2.0.3", 391 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", 392 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" 393 | }, 394 | "ipaddr.js": { 395 | "version": "1.9.1", 396 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", 397 | "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" 398 | }, 399 | "isarray": { 400 | "version": "1.0.0", 401 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", 402 | "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" 403 | }, 404 | "jsonwebtoken": { 405 | "version": "8.5.1", 406 | "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz", 407 | "integrity": "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==", 408 | "requires": { 409 | "jws": "^3.2.2", 410 | "lodash.includes": "^4.3.0", 411 | "lodash.isboolean": "^3.0.3", 412 | "lodash.isinteger": "^4.0.4", 413 | "lodash.isnumber": "^3.0.3", 414 | "lodash.isplainobject": "^4.0.6", 415 | "lodash.isstring": "^4.0.1", 416 | "lodash.once": "^4.0.0", 417 | "ms": "^2.1.1", 418 | "semver": "^5.6.0" 419 | }, 420 | "dependencies": { 421 | "ms": { 422 | "version": "2.1.3", 423 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", 424 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" 425 | } 426 | } 427 | }, 428 | "jwa": { 429 | "version": "1.4.1", 430 | "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", 431 | "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", 432 | "requires": { 433 | "buffer-equal-constant-time": "1.0.1", 434 | "ecdsa-sig-formatter": "1.0.11", 435 | "safe-buffer": "^5.0.1" 436 | } 437 | }, 438 | "jws": { 439 | "version": "3.2.2", 440 | "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", 441 | "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", 442 | "requires": { 443 | "jwa": "^1.4.1", 444 | "safe-buffer": "^5.0.1" 445 | } 446 | }, 447 | "kareem": { 448 | "version": "2.3.2", 449 | "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.3.2.tgz", 450 | "integrity": "sha512-STHz9P7X2L4Kwn72fA4rGyqyXdmrMSdxqHx9IXon/FXluXieaFA6KJ2upcHAHxQPQ0LeM/OjLrhFxifHewOALQ==" 451 | }, 452 | "lodash": { 453 | "version": "4.17.21", 454 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", 455 | "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" 456 | }, 457 | "lodash.includes": { 458 | "version": "4.3.0", 459 | "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", 460 | "integrity": "sha1-YLuYqHy5I8aMoeUTJUgzFISfVT8=" 461 | }, 462 | "lodash.isboolean": { 463 | "version": "3.0.3", 464 | "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", 465 | "integrity": "sha1-bC4XHbKiV82WgC/UOwGyDV9YcPY=" 466 | }, 467 | "lodash.isinteger": { 468 | "version": "4.0.4", 469 | "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", 470 | "integrity": "sha1-YZwK89A/iwTDH1iChAt3sRzWg0M=" 471 | }, 472 | "lodash.isnumber": { 473 | "version": "3.0.3", 474 | "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", 475 | "integrity": "sha1-POdoEMWSjQM1IwGsKHMX8RwLH/w=" 476 | }, 477 | "lodash.isplainobject": { 478 | "version": "4.0.6", 479 | "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", 480 | "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=" 481 | }, 482 | "lodash.isstring": { 483 | "version": "4.0.1", 484 | "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", 485 | "integrity": "sha1-1SfftUVuynzJu5XV2ur4i6VKVFE=" 486 | }, 487 | "lodash.once": { 488 | "version": "4.1.1", 489 | "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", 490 | "integrity": "sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=" 491 | }, 492 | "media-typer": { 493 | "version": "0.3.0", 494 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", 495 | "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" 496 | }, 497 | "memory-pager": { 498 | "version": "1.5.0", 499 | "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz", 500 | "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==", 501 | "optional": true 502 | }, 503 | "merge-descriptors": { 504 | "version": "1.0.1", 505 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", 506 | "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" 507 | }, 508 | "methods": { 509 | "version": "1.1.2", 510 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", 511 | "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" 512 | }, 513 | "mime": { 514 | "version": "1.6.0", 515 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", 516 | "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" 517 | }, 518 | "mime-db": { 519 | "version": "1.48.0", 520 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.48.0.tgz", 521 | "integrity": "sha512-FM3QwxV+TnZYQ2aRqhlKBMHxk10lTbMt3bBkMAp54ddrNeVSfcQYOOKuGuy3Ddrm38I04If834fOUSq1yzslJQ==" 522 | }, 523 | "mime-types": { 524 | "version": "2.1.31", 525 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.31.tgz", 526 | "integrity": "sha512-XGZnNzm3QvgKxa8dpzyhFTHmpP3l5YNusmne07VUOXxou9CqUqYa/HBy124RqtVh/O2pECas/MOcsDgpilPOPg==", 527 | "requires": { 528 | "mime-db": "1.48.0" 529 | } 530 | }, 531 | "mongodb": { 532 | "version": "3.6.10", 533 | "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.6.10.tgz", 534 | "integrity": "sha512-fvIBQBF7KwCJnDZUnFFy4WqEFP8ibdXeFANnylW19+vOwdjOAvqIzPdsNCEMT6VKTHnYu4K64AWRih0mkFms6Q==", 535 | "requires": { 536 | "bl": "^2.2.1", 537 | "bson": "^1.1.4", 538 | "denque": "^1.4.1", 539 | "optional-require": "^1.0.3", 540 | "safe-buffer": "^5.1.2", 541 | "saslprep": "^1.0.0" 542 | } 543 | }, 544 | "mongoose": { 545 | "version": "5.13.3", 546 | "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-5.13.3.tgz", 547 | "integrity": "sha512-q+zX6kqHAvwxf5speMWhq6qF4vdj+x6/kfD5RSKdZKNm52yGmaUygN+zgrtQjBZPFEzG0B3vF6GP0PoAGadE+w==", 548 | "requires": { 549 | "@types/mongodb": "^3.5.27", 550 | "@types/node": "14.x || 15.x", 551 | "bson": "^1.1.4", 552 | "kareem": "2.3.2", 553 | "mongodb": "3.6.10", 554 | "mongoose-legacy-pluralize": "1.0.2", 555 | "mpath": "0.8.3", 556 | "mquery": "3.2.5", 557 | "ms": "2.1.2", 558 | "regexp-clone": "1.0.0", 559 | "safe-buffer": "5.2.1", 560 | "sift": "13.5.2", 561 | "sliced": "1.0.1" 562 | }, 563 | "dependencies": { 564 | "ms": { 565 | "version": "2.1.2", 566 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 567 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" 568 | }, 569 | "safe-buffer": { 570 | "version": "5.2.1", 571 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", 572 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" 573 | } 574 | } 575 | }, 576 | "mongoose-legacy-pluralize": { 577 | "version": "1.0.2", 578 | "resolved": "https://registry.npmjs.org/mongoose-legacy-pluralize/-/mongoose-legacy-pluralize-1.0.2.tgz", 579 | "integrity": "sha512-Yo/7qQU4/EyIS8YDFSeenIvXxZN+ld7YdV9LqFVQJzTLye8unujAWPZ4NWKfFA+RNjh+wvTWKY9Z3E5XM6ZZiQ==" 580 | }, 581 | "mpath": { 582 | "version": "0.8.3", 583 | "resolved": "https://registry.npmjs.org/mpath/-/mpath-0.8.3.tgz", 584 | "integrity": "sha512-eb9rRvhDltXVNL6Fxd2zM9D4vKBxjVVQNLNijlj7uoXUy19zNDsIif5zR+pWmPCWNKwAtqyo4JveQm4nfD5+eA==" 585 | }, 586 | "mquery": { 587 | "version": "3.2.5", 588 | "resolved": "https://registry.npmjs.org/mquery/-/mquery-3.2.5.tgz", 589 | "integrity": "sha512-VjOKHHgU84wij7IUoZzFRU07IAxd5kWJaDmyUzQlbjHjyoeK5TNeeo8ZsFDtTYnSgpW6n/nMNIHvE3u8Lbrf4A==", 590 | "requires": { 591 | "bluebird": "3.5.1", 592 | "debug": "3.1.0", 593 | "regexp-clone": "^1.0.0", 594 | "safe-buffer": "5.1.2", 595 | "sliced": "1.0.1" 596 | }, 597 | "dependencies": { 598 | "debug": { 599 | "version": "3.1.0", 600 | "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", 601 | "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", 602 | "requires": { 603 | "ms": "2.0.0" 604 | } 605 | } 606 | } 607 | }, 608 | "ms": { 609 | "version": "2.0.0", 610 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 611 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" 612 | }, 613 | "negotiator": { 614 | "version": "0.6.2", 615 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", 616 | "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" 617 | }, 618 | "object-assign": { 619 | "version": "4.1.1", 620 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", 621 | "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" 622 | }, 623 | "on-finished": { 624 | "version": "2.3.0", 625 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", 626 | "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", 627 | "requires": { 628 | "ee-first": "1.1.1" 629 | } 630 | }, 631 | "on-headers": { 632 | "version": "1.0.2", 633 | "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", 634 | "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==" 635 | }, 636 | "optional-require": { 637 | "version": "1.0.3", 638 | "resolved": "https://registry.npmjs.org/optional-require/-/optional-require-1.0.3.tgz", 639 | "integrity": "sha512-RV2Zp2MY2aeYK5G+B/Sps8lW5NHAzE5QClbFP15j+PWmP+T9PxlJXBOOLoSAdgwFvS4t0aMR4vpedMkbHfh0nA==" 640 | }, 641 | "parseurl": { 642 | "version": "1.3.3", 643 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", 644 | "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" 645 | }, 646 | "passport": { 647 | "version": "0.4.1", 648 | "resolved": "https://registry.npmjs.org/passport/-/passport-0.4.1.tgz", 649 | "integrity": "sha512-IxXgZZs8d7uFSt3eqNjM9NQ3g3uQCW5avD8mRNoXV99Yig50vjuaez6dQK2qC0kVWPRTujxY0dWgGfT09adjYg==", 650 | "requires": { 651 | "passport-strategy": "1.x.x", 652 | "pause": "0.0.1" 653 | } 654 | }, 655 | "passport-jwt": { 656 | "version": "4.0.0", 657 | "resolved": "https://registry.npmjs.org/passport-jwt/-/passport-jwt-4.0.0.tgz", 658 | "integrity": "sha512-BwC0n2GP/1hMVjR4QpnvqA61TxenUMlmfNjYNgK0ZAs0HK4SOQkHcSv4L328blNTLtHq7DbmvyNJiH+bn6C5Mg==", 659 | "requires": { 660 | "jsonwebtoken": "^8.2.0", 661 | "passport-strategy": "^1.0.0" 662 | } 663 | }, 664 | "passport-local": { 665 | "version": "1.0.0", 666 | "resolved": "https://registry.npmjs.org/passport-local/-/passport-local-1.0.0.tgz", 667 | "integrity": "sha1-H+YyaMkudWBmJkN+O5BmYsFbpu4=", 668 | "requires": { 669 | "passport-strategy": "1.x.x" 670 | } 671 | }, 672 | "passport-strategy": { 673 | "version": "1.0.0", 674 | "resolved": "https://registry.npmjs.org/passport-strategy/-/passport-strategy-1.0.0.tgz", 675 | "integrity": "sha1-tVOaqPwiWj0a0XlHbd8ja0QPUuQ=" 676 | }, 677 | "path-to-regexp": { 678 | "version": "0.1.7", 679 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", 680 | "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" 681 | }, 682 | "pause": { 683 | "version": "0.0.1", 684 | "resolved": "https://registry.npmjs.org/pause/-/pause-0.0.1.tgz", 685 | "integrity": "sha1-HUCLP9t2kjuVQ9lvtMnf1TXZy10=" 686 | }, 687 | "process-nextick-args": { 688 | "version": "2.0.1", 689 | "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", 690 | "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" 691 | }, 692 | "proxy-addr": { 693 | "version": "2.0.7", 694 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", 695 | "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", 696 | "requires": { 697 | "forwarded": "0.2.0", 698 | "ipaddr.js": "1.9.1" 699 | } 700 | }, 701 | "qs": { 702 | "version": "6.7.0", 703 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", 704 | "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==" 705 | }, 706 | "range-parser": { 707 | "version": "1.2.1", 708 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", 709 | "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" 710 | }, 711 | "raw-body": { 712 | "version": "2.4.0", 713 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", 714 | "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", 715 | "requires": { 716 | "bytes": "3.1.0", 717 | "http-errors": "1.7.2", 718 | "iconv-lite": "0.4.24", 719 | "unpipe": "1.0.0" 720 | } 721 | }, 722 | "readable-stream": { 723 | "version": "2.3.7", 724 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", 725 | "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", 726 | "requires": { 727 | "core-util-is": "~1.0.0", 728 | "inherits": "~2.0.3", 729 | "isarray": "~1.0.0", 730 | "process-nextick-args": "~2.0.0", 731 | "safe-buffer": "~5.1.1", 732 | "string_decoder": "~1.1.1", 733 | "util-deprecate": "~1.0.1" 734 | } 735 | }, 736 | "redis": { 737 | "version": "2.6.5", 738 | "resolved": "https://registry.npmjs.org/redis/-/redis-2.6.5.tgz", 739 | "integrity": "sha1-h8Hv9KSJ+Utwhx89CLaYjyOpVoc=", 740 | "requires": { 741 | "double-ended-queue": "^2.1.0-0", 742 | "redis-commands": "^1.2.0", 743 | "redis-parser": "^2.0.0" 744 | } 745 | }, 746 | "redis-commands": { 747 | "version": "1.7.0", 748 | "resolved": "https://registry.npmjs.org/redis-commands/-/redis-commands-1.7.0.tgz", 749 | "integrity": "sha512-nJWqw3bTFy21hX/CPKHth6sfhZbdiHP6bTawSgQBlKOVRG7EZkfHbbHwQJnrE4vsQf0CMNE+3gJ4Fmm16vdVlQ==" 750 | }, 751 | "redis-parser": { 752 | "version": "2.6.0", 753 | "resolved": "https://registry.npmjs.org/redis-parser/-/redis-parser-2.6.0.tgz", 754 | "integrity": "sha1-Uu0J2srBCPGmMcB+m2mUHnoZUEs=" 755 | }, 756 | "regexp-clone": { 757 | "version": "1.0.0", 758 | "resolved": "https://registry.npmjs.org/regexp-clone/-/regexp-clone-1.0.0.tgz", 759 | "integrity": "sha512-TuAasHQNamyyJ2hb97IuBEif4qBHGjPHBS64sZwytpLEqtBQ1gPJTnOaQ6qmpET16cK14kkjbazl6+p0RRv0yw==" 760 | }, 761 | "response-time": { 762 | "version": "2.3.2", 763 | "resolved": "https://registry.npmjs.org/response-time/-/response-time-2.3.2.tgz", 764 | "integrity": "sha1-/6cbq5UtYvfB1Jt0NDVfvGjf/Fo=", 765 | "requires": { 766 | "depd": "~1.1.0", 767 | "on-headers": "~1.0.1" 768 | } 769 | }, 770 | "safe-buffer": { 771 | "version": "5.1.2", 772 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", 773 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" 774 | }, 775 | "safejson": { 776 | "version": "1.0.1", 777 | "resolved": "https://registry.npmjs.org/safejson/-/safejson-1.0.1.tgz", 778 | "integrity": "sha1-W8u5UzuW/OEOY1b0IAF8FqT5yZg=" 779 | }, 780 | "safer-buffer": { 781 | "version": "2.1.2", 782 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 783 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" 784 | }, 785 | "saslprep": { 786 | "version": "1.0.3", 787 | "resolved": "https://registry.npmjs.org/saslprep/-/saslprep-1.0.3.tgz", 788 | "integrity": "sha512-/MY/PEMbk2SuY5sScONwhUDsV2p77Znkb/q3nSVstq/yQzYJOH/Azh29p9oJLsl3LnQwSvZDKagDGBsBwSooag==", 789 | "optional": true, 790 | "requires": { 791 | "sparse-bitfield": "^3.0.3" 792 | } 793 | }, 794 | "semver": { 795 | "version": "5.7.1", 796 | "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", 797 | "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" 798 | }, 799 | "send": { 800 | "version": "0.17.1", 801 | "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", 802 | "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", 803 | "requires": { 804 | "debug": "2.6.9", 805 | "depd": "~1.1.2", 806 | "destroy": "~1.0.4", 807 | "encodeurl": "~1.0.2", 808 | "escape-html": "~1.0.3", 809 | "etag": "~1.8.1", 810 | "fresh": "0.5.2", 811 | "http-errors": "~1.7.2", 812 | "mime": "1.6.0", 813 | "ms": "2.1.1", 814 | "on-finished": "~2.3.0", 815 | "range-parser": "~1.2.1", 816 | "statuses": "~1.5.0" 817 | }, 818 | "dependencies": { 819 | "ms": { 820 | "version": "2.1.1", 821 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", 822 | "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" 823 | } 824 | } 825 | }, 826 | "serve-static": { 827 | "version": "1.14.1", 828 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", 829 | "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", 830 | "requires": { 831 | "encodeurl": "~1.0.2", 832 | "escape-html": "~1.0.3", 833 | "parseurl": "~1.3.3", 834 | "send": "0.17.1" 835 | } 836 | }, 837 | "setprototypeof": { 838 | "version": "1.1.1", 839 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", 840 | "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" 841 | }, 842 | "sift": { 843 | "version": "13.5.2", 844 | "resolved": "https://registry.npmjs.org/sift/-/sift-13.5.2.tgz", 845 | "integrity": "sha512-+gxdEOMA2J+AI+fVsCqeNn7Tgx3M9ZN9jdi95939l1IJ8cZsqS8sqpJyOkic2SJk+1+98Uwryt/gL6XDaV+UZA==" 846 | }, 847 | "sliced": { 848 | "version": "1.0.1", 849 | "resolved": "https://registry.npmjs.org/sliced/-/sliced-1.0.1.tgz", 850 | "integrity": "sha1-CzpmK10Ewxd7GSa+qCsD+Dei70E=" 851 | }, 852 | "sparse-bitfield": { 853 | "version": "3.0.3", 854 | "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", 855 | "integrity": "sha1-/0rm5oZWBWuks+eSqzM004JzyhE=", 856 | "optional": true, 857 | "requires": { 858 | "memory-pager": "^1.0.2" 859 | } 860 | }, 861 | "statuses": { 862 | "version": "1.5.0", 863 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", 864 | "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" 865 | }, 866 | "string_decoder": { 867 | "version": "1.1.1", 868 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", 869 | "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", 870 | "requires": { 871 | "safe-buffer": "~5.1.0" 872 | } 873 | }, 874 | "timestring": { 875 | "version": "5.0.1", 876 | "resolved": "https://registry.npmjs.org/timestring/-/timestring-5.0.1.tgz", 877 | "integrity": "sha512-0VfOVpaTYqBMTEpjwcY5mB+72YYjFI44Z5F2q80ZiIyDn5pRJm+rEV1OEM8xfnf5/FdtckcrTERTp9TbrlMMHw==" 878 | }, 879 | "toidentifier": { 880 | "version": "1.0.0", 881 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", 882 | "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==" 883 | }, 884 | "type-is": { 885 | "version": "1.6.18", 886 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", 887 | "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", 888 | "requires": { 889 | "media-typer": "0.3.0", 890 | "mime-types": "~2.1.24" 891 | } 892 | }, 893 | "unpipe": { 894 | "version": "1.0.0", 895 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", 896 | "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" 897 | }, 898 | "util-deprecate": { 899 | "version": "1.0.2", 900 | "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", 901 | "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" 902 | }, 903 | "utils-merge": { 904 | "version": "1.0.1", 905 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", 906 | "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" 907 | }, 908 | "validator": { 909 | "version": "13.6.0", 910 | "resolved": "https://registry.npmjs.org/validator/-/validator-13.6.0.tgz", 911 | "integrity": "sha512-gVgKbdbHgtxpRyR8K0O6oFZPhhB5tT1jeEHZR0Znr9Svg03U0+r9DXWMrnRAB+HtCStDQKlaIZm42tVsVjqtjg==" 912 | }, 913 | "vary": { 914 | "version": "1.1.2", 915 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", 916 | "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" 917 | }, 918 | "verror": { 919 | "version": "1.10.0", 920 | "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", 921 | "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", 922 | "requires": { 923 | "assert-plus": "^1.0.0", 924 | "core-util-is": "1.0.2", 925 | "extsprintf": "^1.2.0" 926 | } 927 | } 928 | } 929 | } 930 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "node-seed-api", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "dependencies": { 13 | "bcryptjs": "^2.4.3", 14 | "cors": "^2.8.5", 15 | "dotenv": "^10.0.0", 16 | "expeditious-engine-redis": "^0.1.2", 17 | "express": "^4.17.1", 18 | "express-expeditious": "^5.1.1", 19 | "express-validator": "^6.12.1", 20 | "jsonwebtoken": "^8.5.1", 21 | "mongoose": "^5.13.3", 22 | "passport": "^0.4.1", 23 | "passport-jwt": "^4.0.0", 24 | "passport-local": "^1.0.0", 25 | "response-time": "^2.3.2" 26 | } 27 | } 28 | --------------------------------------------------------------------------------