pida
pida

Reputation: 415

User validation process in NodeJS

I'm trying to get this user validation process on the insert method, here is the part of the function that seems like it is not working:

exports.insert = (req, res) => {

    let validEmail = false;


    userModel.findByEmail(req.body.email)
        .then((result)=>{
            if(result) {
                console.log("ok"+result)
            }
            else{
                console.log("nok"+result);
                validEmail = true;
                //returns true when a not used email is posted
            }
        });

    let validPassword = validatePassword(req.body.password);
    console.log(validEmail, validPassword); //always returns false for validEmail

    //If statement to verify if both validEmail and validPassword are "true"

The password validation works properly (pretty straight forward as of now), but what keeps not working is the email validation. Since i'm using the email as the identifier for the authentication I need it to be unique, so I'm using the findByEmail which is as follow :

    exports.findByEmail = (email) => {
    return  User.findOne({"email":email})
        .then((result) => {
            if(result) {
                result = result.toJSON();
                delete result.__v;
                delete result.password;
                return result;
            }else{
                return null;
            }
        })
    };

It does work but it seems like the

validEmail = true 

happens after the if statement. When i console.log if the else statement, it does affect true to validEmail but it doesn't go in the if statement afterwards.

Is there something wrong?

edit : here is the validatePassword function:

function validatePassword(password){
    return password.length>6;
}

Upvotes: 0

Views: 93

Answers (2)

pida
pida

Reputation: 415

Ok so I got the answer thanks to @PeS

Basically i wasn't waiting for the answer of my asynchronous function findByEmail. What I did is chain .then blocks as this, not sure if this is the best way though:

    let validEmail = false;
    let validPassword = req.body.password.length>6;

    userModel.findByEmail(req.body.email)
        .then((result)=>{
            if(!result){
                validEmail = true;
                console.log("1"+validEmail)//returns true
            }
        }).then(() => {
        if(validEmail && validPassword){
            let salt = crypto.randomBytes(16).toString('base64');
            let hash = crypto.createHmac("sha512", salt).update(req.body.password).digest("base64");
            req.body.password = salt + "$" + hash;
            req.body.permissionLevel = 1;
            userModel.createUser(req.body)
                .then((result) => {
                    res.status(201).send({id: result._id});
                })
        }else {
            if (!validEmail && validPassword) {
                res.status(409).send({"Error": "Email already used."});
            }  else if(!validPassword && validEmail){
                res.status(409).send({"Error":"Password is not valid"})
            }else{
                res.status(409).send({"email": "Email already used.", "password": "Password is not valid."})
            }
        }
    });

Upvotes: 0

PeS
PeS

Reputation: 4039

The issue seems to be that you spin off promise hence it runs asynchronously and continue to validate password. This (password validation) should be in the then block of the Promise when email is not found, in your case.

Upvotes: 1

Related Questions