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


function AuthController() {


    async function registerUser(req, res) {
        const {error} = schemaRegister.validate(req.body)
        if (error) {
            return res.status(400).json({
                error: {
                    code: 400,
                    message: error.details[0].message
                }
            })
        }

        const isEmailExist = await User.findOne({email: req.body.email});
        if (isEmailExist) {
            return res.status(400).json({
                error: {
                    code: LOGIN_REGISTER_ERRORS.USER_EXIST.code,
                    message: LOGIN_REGISTER_ERRORS.USER_EXIST.message
                }
            })
        }

        const salt = await bcrypt.genSalt(10);
        const password = await bcrypt.hash(req.body.password, salt);
        const role = await Role.findOne({name: req.body.role});
        const {exportedPublicKeyBuffer, exportedPrivateKeyBuffer} = crypto.encryptDecrypt().generateKeysPair()
        const keysPair = {
            privateKey: exportedPrivateKeyBuffer,
            publicKey: exportedPublicKeyBuffer
        }

        const user = new User({
            username: req.body.username,
            name: req.body.name,
            email: req.body.email,
            password: password,
            keysPair: keysPair
        });

        if (role) {
            if (role.name === ROLES.ROOT.toString()) {
                return res.status(400).json({
                    error: {
                        code: LOGIN_REGISTER_ERRORS.ERROR_ROOT_ROLE.code,
                        message: LOGIN_REGISTER_ERRORS.ERROR_ROOT_ROLE.message
                    }
                })
            } else {
                user.role = role
            }
        } else {
            user.role = await Role.findOne({name: ROLES.USER_STANDARD});
        }

        try {
            const savedUser = await user.save();

            const userToShow = {
                username: savedUser.username,
                name: savedUser.name,
                email: savedUser.email,
                publicKey: savedUser.keysPair.publicKey,
                role: savedUser.role
            }
            return res.status(200).json({
                message: LOGIN_REGISTER_ERRORS.REGISTER_OK.message,
                code: LOGIN_REGISTER_ERRORS.REGISTER_OK.code,
                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 loginUser(req, res) {
        try {
            const {error} = schemaLogin.validate(req.body);
            if (error) return res.status(400).json({
                error: {
                    code: 400,
                    message: error.details[0].message
                }
            })

            const user = await User.findOne({email: req.body.email});
            if (!user) return res.status(404).json({
                error: {
                    code: LOGIN_REGISTER_ERRORS.USER_NOT_FOUND.code,
                    message: LOGIN_REGISTER_ERRORS.USER_NOT_FOUND.message
                }
            });

            const validPassword = await bcrypt.compare(req.body.password, user.password);
            if (!validPassword) return res.status(401).json({
                code: LOGIN_REGISTER_ERRORS.WRONG_PASS.code,
                message: LOGIN_REGISTER_ERRORS.WRONG_PASS.message
            })

            // Creating Token
            const token = jwt.sign({
                id: user._id,
                username: user.username,
                name: user.name
            }, SECRET_TOKEN)

            return res.status(200).header('X-API-Key', token).json({
                code: LOGIN_REGISTER_ERRORS.LOGIN_OK.code,
                message: LOGIN_REGISTER_ERRORS.LOGIN_OK.message,
                token: token
            })
        } 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 schemaRegister = Joi.object({
        username: Joi.string().min(6).max(255).required(),
        name: Joi.string().min(6).max(255).required(),
        email: Joi.string().min(6).max(255).required().email(),
        password: Joi.string().min(6).max(1024).required(),
        role: Joi.string().min(4).max(20)
    }).required()

    const schemaLogin = Joi.object().keys({
        email: Joi.string().min(6).max(255).required().email(),
        password: Joi.string().min(6).max(1024).required()
    }).required()


    return Object.freeze({
        registerUser,
        loginUser,
    })
}

module.exports = AuthController();