Home > Mobile >  Promise {<pending>} of bcrypt inside promise
Promise {<pending>} of bcrypt inside promise

Time:06-24

I have a lambda function that is connected to Mongo via mongoose. The user inputs a name and password on the frontend and the lambda function searches whether the user exists and afterwards the crypted password is compared via bcrypt.

Right now bcrypt gives me {<promise pending>}, when I console.log(match).

However, I can't simply add an await as the check is inside a promise.

require("dotenv").config();
const mongoose = require("mongoose");
const User = require('../server/models/user');
const bcrypt = require('bcryptjs')

exports.handler = async (event, context) => {
  context.callbackWaitsForEmptyEventLoop = false;
  
  mongoose.connect(`${process.env.MONGO_URI}`,{
    useNewUrlParser: true,
    useUnifiedTopology: true,
  }
  );
  
  let {name, password} = JSON.parse(event.body);

 let fd = await new Promise((res,rej)=>User.findOne(
    {
      name:name,
    },
    (err, user) => {
      if (err) {
        rej({
          statusCode: 500,
          body: JSON.stringify({ msg: err.message }),
        });
      } else {
    //==>    const match = await bcrypt.compare(password, JSON.stringify(user.password)); 

 
        if (match) {
        let statusCode = user && match? 200:405
        res({
          statusCode,
          headers: {
            "Access-Control-Allow-Origin": "*", 
            "Content-Type": "application/json",
          },
          body: JSON.stringify({ user}),
        });
      }
      }
    }
  ));
  return fd
};

So basically how can I 'await' bcrypt in that case or how could I write this function in another way? Thanks for reading!

CodePudding user response:

You cannot use await there, because the callback in which it occurs is not an async function.

However, you should better use the promise you can get from findOne:

exports.handler = async (event, context) => {
  context.callbackWaitsForEmptyEventLoop = false;
  
  mongoose.connect(process.env.MONGO_URI, {
    useNewUrlParser: true,
    useUnifiedTopology: true,
  });
  
  const {name, password} = JSON.parse(event.body);
  const user = await User.findOne({name}).exec();
  const match = user && await bcrypt.compare(password, JSON.stringify(user.password)); 
  if (!match) {
    throw {
      statusCode: 405,
      body: "Invalid user or password",
    }
  }
  return {
    statusCode: 200,
    headers: {
      "Access-Control-Allow-Origin": "*", 
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ user}),
  };
};

CodePudding user response:

you could chain the function inside the promise:

let fd = await new Promise((res, rej) =>
  User.findOne(
    {
      name: name,
    },
    (err, user) => {
      if (err) {
        rej({
          statusCode: 500,
          body: JSON.stringify({ msg: err.message }),
        });
      } else {
        bcrypt
          .compare(password, JSON.stringify(user.password))
          .then((match) => {
            if (match) {
              let statusCode = user && match ? 200 : 405;
              res({
                statusCode,
                headers: {
                  "Access-Control-Allow-Origin": "*",
                  "Content-Type": "application/json",
                },
                body: JSON.stringify({ user }),
              });
            }
          });
      }
    }
  )
);
  • Related