Im trying to pass the result of the bcrypt hashing function into the user model below.
I can't seem be able to wrap my head around how to efficiently resolve this promise.
Heres the code:
router.post("/", async (req, res) => {
req.body = sanitize(req.body);
// SHA-256
/* const bitArray = sjcl.hash.sha256.hash(req.body.data[2].value);
const passwordHashed = sjcl.codec.hex.fromBits(bitArray); */
const saltRounds = 10;
const password = req.body.data[2].value;
var passwordHashed;
async function hash() {
return await bcrypt.hash(password, saltRounds, function (err, hash) {});
}
const user = new User({
username: req.body.data[0].value,
email: req.body.data[1].value,
password: hash(),
});
try {
await user.save();
res.status(200).json({ msg: "Success" });
} catch (e) {}
});
That is what I have tried so far, which is probably wrong
Don't pass a callback to bcrypt.hash and then you can await it.
const user = new User({
username: req.body.data[0].value,
email: req.body.data[1].value,
password: await bcrypt.hash(password, saltRounds),
});
Related
Here is the code with async (returns undefined)
userService.register = (username, password) => {
return bcrypt.hash(password, saltRounds, async(err, hash) => {
const newUser = new user({
username: username,
password: hash
})
return await newUser.save()
})
}
and this is the same code with .then, it works correctly
userService.register = (username, password) => {
return bcrypt.hash(password, saltRounds)
.then(hash => {
const newUser = new user({
username: username,
password: hash
})
return newUser.save()
})
}
This is documented behaviour:
Async methods that accept a callback, return a Promise when callback is not specified if Promise support is available
You're passing a callback in your first example, so bcrypt doesn't return a promise.
Another way to write your code is to make the wrapping function async:
userService.register = async (username, password) => {
const hash = await bcrypt.hash(password, saltRounds);
const newUser = new user({
username: username,
password: hash
})
return await newUser.save(); // or just `return newUser.save()`
}
when I call UserService.signUp() from index.js then my var x is undefined. apparently my function singUp() returns back to my router.post function after await hash(). how can I fix this issue? I would like for the signUp function to wait for the hash function to complete, before the function returns.
index.js:
router.post('/register', (req, res) => {
var username = req.body.username,
password = req.body.password,
email = req.body.email
var x = UserService.signUp(username, password, email);
console.log("debug")
if (x.success) {
...
}
})
auth.js:
async function signUp(username, password, email) {
....
try {
var salt = generateSalt()
console.log("generated salt")
var passwordHash = await hash(password, salt)
console.log("generated hash")
} catch (err) {
console.error(err)
}
UserModel.createUser()
return {
success: true,
description: 'User was created'
}
}
function hash(password, salt) {
return pbkdf2(password, salt, 10000, 64, 'sha512');
}
user.js:
function createUser(username, email, salt, hash) {
...
console.log("created user")
return true
}
current output (wrong):
generated salt
debug
POST /register 200 17.164 ms - -
generated hash
created user
desired output:
generated salt
generated hash
created user
debug
POST /register 200 17.164 ms - -
You're not awaiting the function:
var x = UserService.signUp(username, password, email);
Either make the containing function async and await the result:
router.post('/register', async (req, res) => {
//...
var x = await UserService.signUp(username, password, email);
//...
});
Or append a .then() to handle the result of the Promise:
UserService.signUp(username, password, email).then(x => {
console.log("debug")
if (x.success) {
//...
}
});
Have been trying to create a password hash in my nodejs code
But it not working and not showing any error message for me to debug.
And my user is not creating also.
I dont know if there is a better way to do it.
This is my file which is responsible for the code...Model/User.js
const Promise = require('bluebird')
const bcrypt = Promise.promisifyAll(require('bcrypt-nodejs'))
function hashPassword (user) {
const SALT_FACTOR = 8
if (!user.changed('password')) {
return;
}
return bcrypt
.genSaltSyncAsync(SALT_FACTOR)
.then(salt => bcrypt.hashAsync(user.password, salt, null))
.then(hash => {
user.setDataValue('password', hash)
})}
module.exports = (sequelize, DataTypes) => {
const User = sequelize.define('User', {
email: {
type: DataTypes.STRING,
unique: true
},
password: DataTypes.STRING
}, {
hooks: {
beforeCreate: hashPassword,
beforeUpdate: hashPassword,
beforeSave: hashPassword
}
})
User.prototype.comparePassword = function (password) {
return bcrypt.compareAsync(password, this.password)
}
return User }
Does the following snippet help in any way?
const bcrypt = require('bcryptjs');
const userAbc = {
email: 'user#user.com',
password: '1234'
}
async function hashPassword(user) {
try {
const hashedPassword = await bcrypt.hash(user.password, 12);
user.password = hashedPassword;
console.log(user);
} catch (err) {
console.log(err);
}
}
hashPassword(userAbc);
I did change the bcrypt-nodejs to bcryptjs then replace genSaltSyncAsync to genSaltSync and everyother Async to Sync and it worked.
I recieve password through req.body and hash it like this :
const { name, email, password, number } = req.body;
let userExist;
userExist = await User.find({ email: email });
if (userExist.length) {
const err = new Error('User already exists');
return next(err);
}
let hashedPass;
try {
hashedPass = await bcrypt(req.body.password, 12);
} catch (e) {
console.log('error here bro');
return next(e);
}
const createdUser = new User({
name,
email,
password: hashedPass,
number,
ads: []
});
It console logs 'error here bro' and I dont know why .
How can I hash password coming from user with bcrypt js ?
You can also add salt to your password in the following way:
const salt = await bcrypt.genSalt(7);
const hashPassword = await bcrypt.hash(req.body.secret, salt);
Solved the problem by adding hash after bcrypt
bcrypt.hash(....)
I am trying to run the following script in my Node app to check if any users exist and if not, create first admin user. Yet the script simply do nothing, return nothing even while using Try/Catch so can someone please tell me what I am missing / doing wrong here? or how I can possibly catch the error (if any)? Thanks
import pmongo from 'promised-mongo';
import crypto from 'crypto';
const salt = 'DuCDuUR8yvttLU7Cc4';
const MONGODB_URI = 'mongodb://localhost:27017/mydb';
const db = pmongo(MONGODB_URI, {
authMechanism: 'ScramSHA1'
}, ['users']);
async function firstRunCheckAndCreateSuperAdmin(cb) {
const username = 'admin2#test2.com';
try {
const user = await db.users.findOne({ role: 'admin'});
console.log(user);
if(!user) return cb('No user found');
} catch(e) {
cb('Unexpected error occurred');
}
if(!user) {
console.log('No admin detected.');
const adminPassword = crypto.pbkdf2Sync ( 'password', salt, 10000, 512, 'sha512' ).toString ( 'hex' );
await db.users.update({username: username}, {$set: {username: username, password: adminPassword, role: 'admin'}}, {upsert: true});
}
db.close();
process.exit();
}
firstRunCheckAndCreateSuperAdmin(function(err, resultA){
if(err) console.log(err);
});
You are not returning any callback when there is no admin user in the following code snippet
if (!user) {
console.log('No admin detected.');
const adminPassword = crypto.pbkdf2Sync ( 'password', salt, 10000, 512, 'sha512' ).toString ( 'hex' );
await db.users.update({username: username}, {$set: {username: username, password: adminPassword, role: 'admin'}}, {upsert: true});
// call cb(user) here
}
Please see comment.
import pmongo from 'promised-mongo';
import crypto from 'crypto';
const salt = 'DuCDuUR8yvttLU7Cc4';
const MONGODB_URI = 'mongodb://localhost:27017/mydb';
const db = pmongo(MONGODB_URI, {
authMechanism: 'ScramSHA1'
}, ['users']);
async function firstRunCheckAndCreateSuperAdmin(cb) {
const username = 'admin2#test2.com';
try {
const user = await db.users.findOne({
role: 'admin'
});
console.log(user);
//(1) If user is undefined, then launch cb with an error message;
if (!user) return cb('No user found');
} catch (e) {
//(2) If something is wrong, then launch cb with an error message;
cb('Unexpected error occurred');
}
//This part of the code will only be reached if user is defined.
//This is a dead code as if user is undefined, it would have exited at (1)
if (!user) {
console.log('No admin detected.');
const adminPassword = crypto.pbkdf2Sync('password', salt, 10000, 512, 'sha512').toString('hex');
await db.users.update({
username: username
}, {
$set: {
username: username,
password: adminPassword,
role: 'admin'
}
}, {
upsert: true
});
}
//So if user exists, it will close db and exit without calling cb.
db.close();
process.exit();
}
firstRunCheckAndCreateSuperAdmin(function(err, resultA) {
if (err) console.log(err);
});
Note:
If you are using async/await, then you don't need to use callback.
If you are using callback, then you don't need to have a return statement.
If the intention of the function is suppose to have a return value, make sure all code path returns a value.
I have tried to rewrite your code to make it smaller and to remove all node-style callback types of async code from it. I replaced update with insertOne since you only have one user to insert (not multiple to update). Also I have added 500 ms timeout when calling firstRunCheckAndCreateSuperAdmin in case it "hangs". It should log something at the end :)
import pmongo from 'promised-mongo'
import crypto from 'crypto'
import {
promisify
} from 'util'
const pbkdf2 = promisify(crypto.pbkdf2)
const salt = 'DuCDuUR8yvttLU7Cc4'
const MONGODB_URI = 'mongodb://localhost:27017/mydb'
const db = pmongo(MONGODB_URI, {
authMechanism: 'ScramSHA1'
}, ['users']);
const username = 'admin2#test2.com'
async function firstRunCheckAndCreateSuperAdmin() {
let user = await db.users.findOne({
role: 'admin'
});
if (!user) { // no user lets create one
user = await db.users.insertOne({
username: username,
password: (await pbkdf2('password', salt, 10000, 512, 'sha512')).toString('HEX'),
role: 'admin'
});
}
return user
}
const timeout = delay => message => new Promise((_, reject) => setTimeout(reject, delay, new Error(message)))
Promise
.race([firstRunCheckAndCreateSuperAdmin(), timeout(500)('Rejected due to timeout')])
.then(user => console.log(`Got user ${JSON.stringify(user)}`))
.catch(error => console.error(error))