CloudScrapy / controllers / userController.js
userController.js
Raw
const jwt = require('jsonwebtoken');
const Joi = require("@hapi/joi");
const User = require("../models/userModel");
const {LOGIN_REGISTER_ERRORS} = require('../utils/constants');
const crypto = require("../utils/cryptoUtils");
const config = require('config');
const {SECRET_TOKEN} = config.get('tokens');

function UserController() {

    async function getAllUsers(req, res){
        const users = await User.find({})
        let userMap = [];

        users.forEach(function(user) {
            userMap.push(user._id);
        });

        return res.status(200).json({
            code: LOGIN_REGISTER_ERRORS.OK_OPERATION.code,
            message: LOGIN_REGISTER_ERRORS.OK_OPERATION.message,
            data: {userMap}
        })
    }

    async function getUserById(req, res) {
        try {
            const userId = req.params.userId
            const user = await User.findOne({_id: userId});
            if (!user) {
                return res.status(404).json({
                    error: {
                        code: LOGIN_REGISTER_ERRORS.USER_NOT_FOUND.code,
                        message: LOGIN_REGISTER_ERRORS.USER_NOT_FOUND.message
                    }
                })
            } else {
                return res.status(200).json({
                    code: LOGIN_REGISTER_ERRORS.USER_FOUND_OK.code,
                    message: LOGIN_REGISTER_ERRORS.USER_FOUND_OK.message,
                    data: {user}
                })
            }
        } catch (error) {
            return res.status(500).json({
                error: {
                    code: LOGIN_REGISTER_ERRORS.INTERNAL_SERVER_ERROR.code,
                    message: LOGIN_REGISTER_ERRORS.INTERNAL_SERVER_ERROR.message,
                    error: error.toString()
                }
            })
        }
    }

    async function getUserProfileInfo(req, res) {
        try {
            const token = getToken(req)
            const userInfo = jwt.verify(token, SECRET_TOKEN)
            const user = await User.findOne({_id: userInfo.id})
            if (user) {
                return res.status(200).json({
                    code: LOGIN_REGISTER_ERRORS.OK_OPERATION.code,
                    message: LOGIN_REGISTER_ERRORS.OK_OPERATION.message,
                    data: {user}
                })
            }
        } catch (error) {
            return res.status(500).json({
                error: {
                    code: LOGIN_REGISTER_ERRORS.INTERNAL_SERVER_ERROR.code,
                    message: LOGIN_REGISTER_ERRORS.INTERNAL_SERVER_ERROR.message,
                    error: error.toString()
                }
            })
        }
    }

    async function getUserByUsername(req, res) {
        try {
            const username = req.params.username
            const user = await User.findOne({username: username});
            if (!user) {
                return res.status(404).json({
                    error: {
                        code: LOGIN_REGISTER_ERRORS.USER_NOT_FOUND.code,
                        message: LOGIN_REGISTER_ERRORS.USER_NOT_FOUND.message
                    }
                })
            } else {
                return res.status(200).json({
                    code: LOGIN_REGISTER_ERRORS.USER_FOUND_OK.code,
                    message: LOGIN_REGISTER_ERRORS.USER_FOUND_OK.message,
                    data: {user}
                })
            }
        } catch (error) {
            return res.status(500).json({
                error: {
                    code: LOGIN_REGISTER_ERRORS.INTERNAL_SERVER_ERROR.code,
                    message: LOGIN_REGISTER_ERRORS.INTERNAL_SERVER_ERROR.message,
                    error: error.toString()
                }
            })
        }
    }

    async function deleteUserById(req, res) {
        try {
            const userId = req.params.userId
            const user = await User.findOne({_id: userId});
            if (!user) {
                return res.status(404).json({
                    error: {
                        code: LOGIN_REGISTER_ERRORS.USER_NOT_FOUND.code,
                        message: LOGIN_REGISTER_ERRORS.USER_NOT_FOUND.message
                    }
                })
            } else {
                if (user.username === 'root') {
                    return res.status(403).json({
                        code: LOGIN_REGISTER_ERRORS.ERROR_ROOT_DELETE.code,
                        message: LOGIN_REGISTER_ERRORS.ERROR_ROOT_DELETE.message
                    })
                } else {
                    await User.deleteOne({_id: userId});
                    return res.status(200).json({
                        code: LOGIN_REGISTER_ERRORS.DELETE_OK.code,
                        message: LOGIN_REGISTER_ERRORS.DELETE_OK.message
                    })
                }
            }
        } catch (error) {
            return res.status(500).json({
                error: {
                    code: LOGIN_REGISTER_ERRORS.INTERNAL_SERVER_ERROR.code,
                    message: LOGIN_REGISTER_ERRORS.INTERNAL_SERVER_ERROR.message,
                    error: error.toString()
                }
            })
        }
    }

    async function updateUserById(req, res) {
        try {
            const {error} = schemaUpdater.validate(req.body)
            if (error) {
                return res.status(400).json({
                    error: {
                        code: 400,
                        message: error.details[0].message
                    }
                })
            }
            const userId = req.params.userId
            const userToUpdate = req.body
            const userUpdated = await User.findByIdAndUpdate(userId, userToUpdate, {new: true});
            if (!userUpdated) {
                return res.status(404).json({
                    error: {
                        code: LOGIN_REGISTER_ERRORS.USER_NOT_FOUND.code,
                        message: LOGIN_REGISTER_ERRORS.USER_NOT_FOUND.message
                    }
                })
            }else {
                const userToShow = {
                    username: userUpdated.username,
                    name: userUpdated.name,
                    email: userUpdated.email,
                    publicKey: userUpdated.keysPair.publicKey,
                    role: userUpdated.role
                }
                return res.status(200).json({
                        code: LOGIN_REGISTER_ERRORS.USER_UPDATED_OK.code,
                        message: LOGIN_REGISTER_ERRORS.USER_UPDATED_OK.message,
                        data: userToShow
                })
            }
        } catch (error) {
            return res.status(500).json({
                error: {
                    code: LOGIN_REGISTER_ERRORS.INTERNAL_SERVER_ERROR.code,
                    message: LOGIN_REGISTER_ERRORS.INTERNAL_SERVER_ERROR.message,
                    error: error.toString()
                }
            })
        }
    }

    async function refreshKeysPairById(req, res) {
        try {
            const userId = req.params.userId
            const {exportedPublicKeyBuffer, exportedPrivateKeyBuffer} = crypto.encryptDecrypt().generateKeysPair()
            const keysPair = {
                privateKey: exportedPrivateKeyBuffer,
                publicKey: exportedPublicKeyBuffer
            }
            const userUpdated = await User.findByIdAndUpdate(userId, {keysPair}, {new: true});
            if (!userUpdated) {
                return res.status(404).json({
                    error: {
                        code: LOGIN_REGISTER_ERRORS.USER_NOT_FOUND.code,
                        message: LOGIN_REGISTER_ERRORS.USER_NOT_FOUND.message
                    }
                })
            } else {
                return res.status(204).json({
                    code: LOGIN_REGISTER_ERRORS.UPDATED_NO_CONTENT.code,
                    message: LOGIN_REGISTER_ERRORS.UPDATED_NO_CONTENT.message
                })
            }
        } catch (error) {
            return res.status(500).json({
                error: {
                    code: LOGIN_REGISTER_ERRORS.INTERNAL_SERVER_ERROR.code,
                    message: LOGIN_REGISTER_ERRORS.INTERNAL_SERVER_ERROR.message,
                    error: error.toString()
                }
            })
        }
    }


    const schemaUpdater = Joi.object({
        name: Joi.string().min(6).max(255).required(),
        password: Joi.string().min(6).max(1024).required(),
        role: Joi.string().min(4).max(20)
    })


    function getToken(req) {
        return req.header('X-API-Key')
    }



    return Object.freeze({
        getUserById,
        getAllUsers,
        getUserProfileInfo,
        getUserByUsername,
        deleteUserById,
        updateUserById,
        refreshKeysPairById
    })
}

module.exports = UserController();