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 }),
});
}
});
}
}
)
);