| "express-jwt": "^7.7.2", | "express-jwt": "^7.7.2", | ||||
| "helmet": "^5.1.0", | "helmet": "^5.1.0", | ||||
| "joi": "^17.6.0", | "joi": "^17.6.0", | ||||
| "joi-objectid": "^4.0.2", | |||||
| "jsonwebtoken": "^8.5.1", | "jsonwebtoken": "^8.5.1", | ||||
| "migrate-mongo": "^9.0.0", | "migrate-mongo": "^9.0.0", | ||||
| "mongodb": "^4.6.0", | "mongodb": "^4.6.0", | ||||
| "@sideway/pinpoint": "^2.0.0" | "@sideway/pinpoint": "^2.0.0" | ||||
| } | } | ||||
| }, | }, | ||||
| "node_modules/joi-objectid": { | |||||
| "version": "4.0.2", | |||||
| "resolved": "https://registry.npmjs.org/joi-objectid/-/joi-objectid-4.0.2.tgz", | |||||
| "integrity": "sha512-OjYM+wK/JGo2bSb9ADEyzxxROJPZYtrqIwBbywpJ2a98oKlbLtWTKvpzmrnXzou69Ey9EsjHsFvZYzpjeCdKuA==" | |||||
| }, | |||||
| "node_modules/js-yaml": { | "node_modules/js-yaml": { | ||||
| "version": "4.1.0", | "version": "4.1.0", | ||||
| "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", | ||||
| "@sideway/pinpoint": "^2.0.0" | "@sideway/pinpoint": "^2.0.0" | ||||
| } | } | ||||
| }, | }, | ||||
| "joi-objectid": { | |||||
| "version": "4.0.2", | |||||
| "resolved": "https://registry.npmjs.org/joi-objectid/-/joi-objectid-4.0.2.tgz", | |||||
| "integrity": "sha512-OjYM+wK/JGo2bSb9ADEyzxxROJPZYtrqIwBbywpJ2a98oKlbLtWTKvpzmrnXzou69Ey9EsjHsFvZYzpjeCdKuA==" | |||||
| }, | |||||
| "js-yaml": { | "js-yaml": { | ||||
| "version": "4.1.0", | "version": "4.1.0", | ||||
| "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", |
| "express-jwt": "^7.7.2", | "express-jwt": "^7.7.2", | ||||
| "helmet": "^5.1.0", | "helmet": "^5.1.0", | ||||
| "joi": "^17.6.0", | "joi": "^17.6.0", | ||||
| "joi-objectid": "^4.0.2", | |||||
| "jsonwebtoken": "^8.5.1", | "jsonwebtoken": "^8.5.1", | ||||
| "migrate-mongo": "^9.0.0", | "migrate-mongo": "^9.0.0", | ||||
| "mongodb": "^4.6.0", | "mongodb": "^4.6.0", |
| type: String, | type: String, | ||||
| required: true | required: true | ||||
| }, | }, | ||||
| role: { | |||||
| roles: { | |||||
| type: String | type: String | ||||
| }, | }, | ||||
| tokens: [{ | tokens: [{ |
| const Auth = require('../database/models/token') | |||||
| const authMediator = require('../mediator/authMediator') | |||||
| const token = async (req, res, next) => { | |||||
| try { | |||||
| if (!req.body.email || !req.body.password){ | |||||
| return res.status(400).send('Pass credentials') | |||||
| } | |||||
| const result = await authMediator.token() | |||||
| if(!result.succeeded){ | |||||
| res.status(401).send(result.error) | |||||
| } | |||||
| return res.status(200).send(result.value) | |||||
| } catch (e) { | |||||
| next(e) | |||||
| } | |||||
| } | |||||
| const logout = async (req, res) => { | |||||
| const result = await Auth.destroyToken(req.body.token) | |||||
| if (!result) { | |||||
| return res.status(404).send('No user has the token provided!') | |||||
| } | |||||
| return res.send('Auth ' + req.body.token + ' invalidated!') | |||||
| } | |||||
| const refreshUserToken = async (req, res) => { | |||||
| const form = { | |||||
| token: req.body.token | |||||
| } | |||||
| const result = await Auth.refreshAuthToken(form.token) | |||||
| if (!result) { | |||||
| return res.status(404).send('Auth not valid!') | |||||
| } | |||||
| return res.status(201).send('Auth ' + result + ' refreshed successfully!') | |||||
| } | |||||
| module.exports = { loginUser: token, logout, refreshUserToken } |
| const Token = require('../database/models/token') | |||||
| const bcrypt = require('bcryptjs') | |||||
| const loginUser = async (req, res, next) => { | |||||
| try { | |||||
| const findUser = await Token.findByCredentials(req.body.email, req.body.password) | |||||
| if (!findUser) { | |||||
| return res.status(400).send('Wrong credentials!') | |||||
| } | |||||
| const isValidPassword = await bcrypt.compare(req.body.password, findUser.password) | |||||
| if (!isValidPassword) { | |||||
| return res.status(400).send('Wrong credentials!') | |||||
| } | |||||
| const token = await Token.generateAuthToken(findUser) | |||||
| return res.status(201).send(findUser) | |||||
| } catch (e) { | |||||
| next(e) | |||||
| } | |||||
| } | |||||
| const logout = async (req, res) => { | |||||
| const result = await Token.destroyToken(req.body.token) | |||||
| if (!result) { | |||||
| return res.status(404).send('No user has the token provided!') | |||||
| } | |||||
| return res.send('Token ' + req.body.token + ' invalidated!') | |||||
| } | |||||
| const refreshUserToken = async (req, res) => { | |||||
| const form = { | |||||
| token: req.body.token | |||||
| } | |||||
| const result = await Token.refreshAuthToken(form.token) | |||||
| if (!result) { | |||||
| return res.status(404).send('Token not valid!') | |||||
| } | |||||
| return res.status(201).send('Token ' + result + ' refreshed successfully!') | |||||
| } | |||||
| module.exports = { loginUser, logout, refreshUserToken } |
| const bcrypt = require("bcryptjs/dist/bcrypt") | |||||
| const User = require("../database/models/user") | const User = require("../database/models/user") | ||||
| const { getUserValidator } = require("../validators/users") | |||||
| const { getUserValidator, getIdValidator, getUpdatedUserValidator } = require("../validators/users") | |||||
| const mediator = require('../mediator/userMediator') | |||||
| const getUsers = async (req, res, next) => { | const getUsers = async (req, res, next) => { | ||||
| const allUsers = await User.find({}) | const allUsers = await User.find({}) | ||||
| } | } | ||||
| const getUser = async (req, res, next) => { | const getUser = async (req, res, next) => { | ||||
| const result = getUserValidator.validate(req.body) | |||||
| console.log(result) | |||||
| try { | try { | ||||
| const id = req.params.id | const id = req.params.id | ||||
| if (!id) { | |||||
| return res.status(400).send('Bad request') | |||||
| } | |||||
| const user = await User.findById(id) | |||||
| if (!user) { | |||||
| return res.status(404).send("User with the id of: " + id + " doesnt exist") | |||||
| const errId = getIdValidator.validate(id).error | |||||
| if (errId) { | |||||
| return res.status(404).send(errId.message) | |||||
| } | } | ||||
| const result = await mediator.getUser(id) | |||||
| return res.json(user) | |||||
| if (!result.succeeded) { | |||||
| return res.status(400).send(result.error) | |||||
| } | |||||
| return res.status(200).json(result.value) | |||||
| } catch (e) { | } catch (e) { | ||||
| next(e) | next(e) | ||||
| } | } | ||||
| const createUser = async (req, res, next) => { | const createUser = async (req, res, next) => { | ||||
| try { | try { | ||||
| const userModel = req.body | const userModel = req.body | ||||
| if (Object.entries(userModel).length === 0) { | |||||
| return res.status(400).send('Object cant be empty') | |||||
| } | |||||
| const err = getUserValidator.validate(userModel).error | const err = getUserValidator.validate(userModel).error | ||||
| if (err) { | if (err) { | ||||
| return res.status(401).send(err.message) | |||||
| return res.status(404).send(err.message) | |||||
| } | |||||
| const result = await mediator.createUser(userModel) | |||||
| if (!result.succeeded) { | |||||
| return res.status(400).send(result.error) | |||||
| } | } | ||||
| const newUser = new User(userModel) | |||||
| newUser.password = await bcrypt.hash(newUser.password, 8) | |||||
| await newUser.save() | |||||
| return res.status(201).json(newUser) | |||||
| return res.status(201).json(result.value) | |||||
| } catch (e) { | } catch (e) { | ||||
| next(e) | next(e) | ||||
| } | } | ||||
| const updateUser = async (req, res, next) => { | const updateUser = async (req, res, next) => { | ||||
| try { | try { | ||||
| const id = req.params.id | const id = req.params.id | ||||
| const objBody = req.body | |||||
| if (Object.entries(objBody).length == 0) { | |||||
| return res.status(400).send('Invalid input parameters') | |||||
| const errId = getIdValidator.validate(id).error | |||||
| if (errId) { | |||||
| return res.status(400).send(errId.message) | |||||
| } | } | ||||
| const err = getUserValidator.validate(objBody).error | |||||
| const objBody = req.body | |||||
| const err = getUpdatedUserValidator.validate(objBody).error | |||||
| if (err) { | if (err) { | ||||
| return res.status(400).send(err.message) | return res.status(400).send(err.message) | ||||
| } | } | ||||
| let user = await User.findById(id); | |||||
| if (!user) { | |||||
| return res.status(404).send("User with the id of: " + id + " doesnt exist") | |||||
| const result = await mediator.updateUser(id, objBody) | |||||
| if (!result.succeeded) { | |||||
| return res.status(400).send(result.error) | |||||
| } | } | ||||
| return res.status(200).send(result.value) | |||||
| } catch (e) { | |||||
| next(e) | |||||
| } | |||||
| } | |||||
| const updatedUser = { | |||||
| name: objBody.name, | |||||
| password: objBody.password, | |||||
| email: objBody.email | |||||
| const deleteUser = async (req, res, next) => { | |||||
| try { | |||||
| const id = req.params.id | |||||
| const errId = getIdValidator.validate(id).error | |||||
| if (errId) { | |||||
| return res.status(400).send(errId.message) | |||||
| } | } | ||||
| await User.updateOne({ _id: req.params.id }, updatedUser) | |||||
| return res.status(200).send('User updated successfully') | |||||
| const result = await mediator.deleteUser(id) | |||||
| if (!result.succeeded) { | |||||
| return res.status(400).send(result.error) | |||||
| } | |||||
| return res.status(204).send(result.value) | |||||
| } catch (e) { | } catch (e) { | ||||
| next(e) | next(e) | ||||
| } | } | ||||
| const updateUserContacts = async (req, res, next) => { | const updateUserContacts = async (req, res, next) => { | ||||
| try { | try { | ||||
| userFound = true | |||||
| const userFound = true | |||||
| if (!userFound) { | if (!userFound) { | ||||
| return res.status(404).send('user not found') | return res.status(404).send('user not found') | ||||
| } | } | ||||
| if (Object.entries(req.body).length == 0) { | |||||
| if (!req.body) { | |||||
| return res.status(400).send('invalid input parameters') | return res.status(400).send('invalid input parameters') | ||||
| } | } | ||||
| return res.status(200).send('user contacts updated successfully') | return res.status(200).send('user contacts updated successfully') | ||||
| } | } | ||||
| } | } | ||||
| const deleteUser = async (req, res, next) => { | |||||
| try { | |||||
| const id = req.params.id | |||||
| if (!id) { | |||||
| return res.status(400).send('You need to provide valid Id') | |||||
| } | |||||
| const user = await User.findById(id) | |||||
| if (!user) { | |||||
| return res.status(404).send("User with the id of: " + id + " doesnt exist") | |||||
| } | |||||
| await User.deleteOne(user) | |||||
| return res.status(204).send('Deleting user with id of ' + id) | |||||
| } catch (e) { | |||||
| next(e) | |||||
| } | |||||
| } | |||||
| module.exports = { getUsers, getUser, createUser, updateUserContacts, updateUser, deleteUser } | |||||
| module.exports = { getUsers, getUser, createUser, updateUser, updateUserContacts, deleteUser } |
| const Auth = require("../database/models/token"); | |||||
| const bcrypt = require("bcryptjs"); | |||||
| const token = async (email, password) => { | |||||
| const foundUser = await Auth.findByCredentials(email, password) | |||||
| if (!foundUser) { | |||||
| return { | |||||
| succeeded: false, | |||||
| value: null, | |||||
| error: 'Wrong credentials!' | |||||
| } | |||||
| } | |||||
| const isValidPassword = await bcrypt.compare(password, foundUser.password) | |||||
| if (!isValidPassword) { | |||||
| return { | |||||
| succeeded: false, | |||||
| value: null, | |||||
| error: 'Wrong credentials!' | |||||
| } | |||||
| } | |||||
| const token = await Auth.generateAuthToken(foundUser) | |||||
| return { | |||||
| succeeded: true, | |||||
| value: token, | |||||
| error: null | |||||
| } | |||||
| } | |||||
| module.exports = {token} |
| const bcrypt = require("bcryptjs/dist/bcrypt") | |||||
| const User = require("../database/models/user") | |||||
| const { getUserValidator } = require("../validators/users") | |||||
| const getUser = async (id) => { | |||||
| const user = await User.findById(id) | |||||
| if (!user) { | |||||
| return { | |||||
| succeeded: false, | |||||
| value: null, | |||||
| error: 'User not found!' | |||||
| } | |||||
| } | |||||
| return { | |||||
| succeeded: true, | |||||
| value: user, | |||||
| error: null | |||||
| } | |||||
| } | |||||
| const createUser = async (user) => { | |||||
| const foundMail = await User.find({ email: user.email }) | |||||
| if (foundMail.length) { | |||||
| return { | |||||
| succeeded: false, | |||||
| value: null, | |||||
| error: 'User with email already exists!' | |||||
| } | |||||
| } | |||||
| const newUser = new User(user) | |||||
| newUser.password = await bcrypt.hash(newUser.password, 8) | |||||
| await User.create(newUser) | |||||
| return { | |||||
| succeeded: true, | |||||
| value: newUser, | |||||
| error: null | |||||
| } | |||||
| } | |||||
| const updateUser = async (id, body) => { | |||||
| let user = await User.findById(id); | |||||
| if (!user) { | |||||
| return { | |||||
| succeeded: false, | |||||
| value: null, | |||||
| error: 'User with id ' + id + ' does not exist!' | |||||
| } | |||||
| } | |||||
| const updatedUser = { | |||||
| name: body.name, | |||||
| roles: body.roles | |||||
| } | |||||
| await User.updateOne({ _id: id }, updatedUser) | |||||
| return { | |||||
| succeeded: true, | |||||
| value: 'User updated successfully!', | |||||
| error: null | |||||
| } | |||||
| } | |||||
| const deleteUser = async (id) => { | |||||
| let user = await User.findById(id) | |||||
| if (!user) { | |||||
| return { | |||||
| succeeded: false, | |||||
| value: null, | |||||
| error: 'User with id ' + id + ' does not exist!' | |||||
| } | |||||
| } | |||||
| await User.deleteOne(user) | |||||
| return { | |||||
| succeeded: true, | |||||
| value: null, | |||||
| error: null | |||||
| } | |||||
| } | |||||
| module.exports = {getUser, createUser, updateUser, deleteUser} |
| const config = require('config') | const config = require('config') | ||||
| const errorLogger = (err, req, res, next) => { | const errorLogger = (err, req, res, next) => { | ||||
| //console.error(err) | |||||
| if (config.util.getEnv('NODE_ENV') === 'development') | if (config.util.getEnv('NODE_ENV') === 'development') | ||||
| logger.error(err) | logger.error(err) | ||||
| const express = require('express') | const express = require('express') | ||||
| const router = new express.Router() | const router = new express.Router() | ||||
| const endpoints = require('../endpoints/token') | |||||
| const endpoints = require('../endpoints/auth') | |||||
| router.post('/auth/token', endpoints.loginUser) | router.post('/auth/token', endpoints.loginUser) |
| const app = express() | const app = express() | ||||
| const port = process.env.NODE_ENV === 'production' ? 80 : 3001 | const port = process.env.NODE_ENV === 'production' ? 80 : 3001 | ||||
| require('./database/mongoose') | require('./database/mongoose') | ||||
| const docs = require('./swagger.js'); | |||||
| const docs = require('./swagger.js') | |||||
| const swaggerUI = require('swagger-ui-express') | const swaggerUI = require('swagger-ui-express') | ||||
| const { errorLogger, errorResponder } = require('./middleware/errorHandling.js') | const { errorLogger, errorResponder } = require('./middleware/errorHandling.js') | ||||
| const requestLogging = require('./middleware/requestLogging.js') | const requestLogging = require('./middleware/requestLogging.js') | ||||
| app.use(errorLogger); | app.use(errorLogger); | ||||
| app.use(errorResponder); | app.use(errorResponder); | ||||
| app.use(express.json()) | app.use(express.json()) | ||||
| app.use('/api-docs', swaggerUI.serve, swaggerUI.setup(docs)) | |||||
| app.use('/swagger', swaggerUI.serve, swaggerUI.setup(docs)) | |||||
| app.use(requestLogging) | app.use(requestLogging) | ||||
| app.use(cors()) | app.use(cors()) | ||||
| app.use(helmet()) | app.use(helmet()) |
| const Joi = require("joi"); | const Joi = require("joi"); | ||||
| Joi.objectId = require('joi-objectid')(Joi) | |||||
| const schema = { | |||||
| getUserValidator: Joi.object({ | |||||
| name: Joi.string().min(2).required(), | |||||
| password: Joi.string().min(8).regex(/[a-zA-Z0-9]{3,30}/).required(), | |||||
| email: Joi.string().email().required(), | |||||
| role: Joi.string() | |||||
| }) | |||||
| } | |||||
| module.exports = schema | |||||
| const getIdValidator = Joi.objectId().required(); | |||||
| const getUserValidator = Joi.object({ | |||||
| name: Joi.string().min(2).required(), | |||||
| password: Joi.string().min(8).regex(/[a-zA-Z0-9]{3,30}/).required(), | |||||
| email: Joi.string().email().required(), | |||||
| roles: Joi.string() | |||||
| }) | |||||
| const getUpdatedUserValidator = Joi.object({ | |||||
| name: Joi.string().min(2).required(), | |||||
| roles: Joi.string() | |||||
| }) | |||||
| module.exports = {getUserValidator, getIdValidator, getUpdatedUserValidator} |