I need to compare passwords with Bcrypt library.
here's my code:
bcrypt.js
const bcrypt = require('bcrypt');
const saltRounds = 10;
var Bcrypt = () => {
}
Bcrypt.encrypt = async function(password) {
const hashedPassword = await bcrypt.hash(password, saltRounds)
return hashedPassword
}
Bcrypt.compare = async function(password, hashed_password) {
await bcrypt.compare(password, hashed_password, function(err, result) {
return result;
});
}
module.exports = Bcrypt;
userMethods.js
const Bcrypt = require('../../global-functions/bcrypt');
var login = async(req) => {
var user = {
username: req.body.username,
password: req.body.password
}
if (!user.username || !user.password) {
return ({ error: "Login details are required to continue." });
}
return new Promise((resolve, reject) => {
db.query("SELECT name,username,email,password FROM users WHERE username = ?", [req.body.username], function(err, rows) {
if (err) {
console.log("error: ", err);
reject(err);
} else {
var compared_result = Bcrypt.compare(user.password, rows[0].password); // returns **undefined**
}
if (compared_result) {
resolve({ success: compared_result, username: rows[0].username });
} else {
resolve({ error: "wrong username or password!" });
}
});
});
}
when I try to add await before Bcrypt.compare I get an "await is only valid in async function" error.
I would appreciate any help.
Do you want to put it before this Bcrypt.compare
Bcrypt.compare = async function(password, hashed_password) {
await bcrypt.compare(password, hashed_password, function(err, result) {
return result;
});
}
Then you have to write this code into a outer function and give async there then use await inside
async function()
{
await Bcrypt.compare = async function(password, hashed_password) {
await bcrypt.compare(password, hashed_password, function(err, result) {
return result;
});
}
}
I think this might solve your problem
Related
I am currently working on an API on node.js. I have seen other similar posts but the solution does not work for me. Below are my codes to retrieve user by email and compare the password. I enter the correct credentials but the compare is always returning false. Am I missing out something?
const bcrypt = require('bcrypt');
const saltRounds = 10;
app.post('/auth', function (req, response) {
let query = `select * from users where email = "${req.body.email}"`;
console.warn(req.body.email);
databaseConnector.query(query, (error, result) => {
if (error) {
console.log(error, 'Error occurred with /auth/ API...');
}
if (result.length > 0) {
console.warn(req.body.password, result[0].password);
bcrypt.compare(req.body.password, result[0].password, function (err, res) {
console.warn(res, 'bcryot response')
// if res == true, password matched
// else wrong password
if (res) {
var token = jwt.sign({ userID: result.id }, 'todo-app-super-shared-secret', { expiresIn: '2h' });
response.send({
token: token,
id: result[0].id,
firstName: result[0].firstName
})
}
else {
return response.sendStatus(401);
}
});
}
else {
return response.sendStatus(401);
}
})
});
this is my code :
const user = await User.findOne({ email }).select('+password');
console.log(' user value : ', user);
const boolean = await user.comparePassword(password, user.password);
console.log('boolean value : ', boolean);
The results of my flags in console :
user value : {
role: 'user',
passwordChangedAt: 2021-04-14T02:19:54.689Z,
_id: 6074b03b28f33810a528d61f,
name: 'Javier',
password: '$2a$12$cSsURwyoGGd2j9kreuwnGur3pYaTmnY3K2vjXRSJpDhptDwy0t4lG',
__v: 0
}
boolean value : undefined
So, boolean var is not waiting, and i don't know why. These is my function in my userschema :
userSchema.methods.comparePassword = catchAsync(async function comparePassword(
password,
userPassword
) {
const aux = await bcrypt.compare(password, userPassword);
return aux;
});
```
How can i force boolean to wait for the result of comparePassword function ?
userSchema.methods.comparePassword = async (password, userPassword) => {
return new Promise((resolve, reject) => {
bcrypt.compare(password, userPassword, (err, result) => {
if (err) {
resolve(false);
}
if (result == true) {
resolve(true);
} else {
resolve(false);
}
})
});
}
I'm trying to get my login api working inside azure function, but it keeps saying await is only valid in async function. This is an async function so I'm just super confused.
This line
const user = await db.collection('users').findOne({ email: userLoggingIn.email })
is throwing the error.
const jwt = require("jsonwebtoken");
const bcrypt = require("bcrypt");
var MongoClient = require('mongodb').MongoClient;
module.exports = async function (context, req) {
MongoClient.connect(process.env.CosmosDBConnectionString, (err, client) => {
let userLoggingIn = ({ email, password } = req.body);
console.log("userLoggingIn");
console.log(userLoggingIn.email);
let send = response(client, context);
if (err) send(500, err.message);
console.log("DBNAME: " + process.env.dbName);
let user;
let db = client.db(process.env.dbName);
const user = await db.collection('users').findOne({ email: userLoggingIn.email })
console.log("USER");
console.log(user);
let userName= user.instagramName;
if (!user) {
send(401, { message: "Auth failed" });
}
const { username } = user;
console.log("PASSWORD");
console.log(context.req.password);
console.log(user.password);
const goodPassword = bcrypt.compareSync(context.req.password, user.password);
if (!goodPassword) {
return send(401, { message: "Auth failed" });
}
const token = jwt.sign(
{
email: user.email,
userId: user._id,
username: userName
},
"secret_this_should_be_longer",
{ expiresIn: "1h" }
);
context.res = { status: 200, token: token, expiresIn: 3600, userId: user._id, username: username};
})
}
function response(client, context) {
return function (status, body) {
context.res = {
status: status,
body: body
};
client.close();
context.done();
};
}
MongoClient.connect(process.env.CosmosDBConnectionString, (err, client) => {
on this line, the annonymous callback function receiving err and client as parameter is the function that needs to be async
MongoClient.connect(process.env.CosmosDBConnectionString, async (err, client) => {
I'm using koa to reset a password, wanting to use .save in order to fire the schema.pre('save' ).
data was returning with findOneAndUpdate, but not when I use .save.
what's the magic combination to make this return the .save doc properly with the await/asyncs?
r.post("/public/auth/resetpass", async (ctx, next) => {
const values = ctx.request.body;
const query = {
email: values.email,
resetPasswordToken: values.resetPasswordToken,
resetPasswordExpires: {
$gt: new Date(new Date())
}
};
const update = {
password: values.password,
resetPasswordToken: null,
resetPasswordExpires: null
};
// let userFound = null;
await User.findOne(query,async function(err, user) {
if (err) {
console.log("*** err");
next(err);
} else {
if (_.isEmpty(user)) {
ctx.status = 200;
ctx.body = {
error: true,
message: "token is incorrect or time has expired for password reset"
};
} else {
user.password = values.password;
await user.save(function(err, doc) {
if (err) {
console.log('***err saving');
next(err);
} else {
//console.log fires, but ctx body doesn't return
console.log ('***saved, writing poco');
ctx.body = userToPoco(doc);
}
});
}
}
});
});
ultimately switched to a promise.
await user.save().then (doc =>{
ctx.body = doc;
});
I'm using bcrypt to authenticate the users in my system. When i register an user, with the code:
UserSchema.pre("save", async function(next) {
var user = this;
if (user.isModified('password')) {
var salt = bcrypt.genSaltSync(10);
await bcrypt.hash(user.password, salt, null, function(err, hash) {
if(err){
console.log(err);
}else {
user.password = hash;
}
});
}
next();
});
Ok, the hash is created and save in mongo. My problema is, when i log in with this user, any password works. Here's is my compare function:
UserSchema.methods.authenticate = async function(password) {
var user = this;
var isAuthenticaded = await bcrypt.compare(password, user.password,
function(err, res){
if(res){
return true;
}else{
return false;
}
});
return isAuthenticaded;
};
I call the function 'authenticate' with passport:
if (!user.authenticate(password)) {
return done(null, false, {message: 'Senha inválida.'});
}
Someone could help?
[EDIT] - I think the problem is asynchronous calls. Modified to syncrhonous and it works! I will apreciate if someone discover where is the problem with asyncrhonous calls
About async implementation.
UserSchema.pre('save', async function save(next) {
if (!this.isModified('password')) return next();
try {
const salt = await bcrypt.genSalt(10);
this.password = await bcrypt.hash(this.password, salt);
return next();
} catch (err) {
return next(err);
}
});
UserSchema.methods.authenticate = async function(password) {
return bcrypt.compare(password, this.password);
};
And now, if user using our async authentication method, we have to await for result.
if (!await user.authenticate(password)) {
return done(null, false, {message: 'Senha inválida.'});
}
You can read more about pre.