Why is the functions execute in finally in node js - node.js

In here my req.body.newTransactionPassword="1234";
i want encrypt that value but case is function is execute finally.I want get it into my order.Is that possible ..?
console.log("1");
var nwtp=req.body.newTransactionPassword;
var setPassword = function(nwtp,cb){
console.log("2");
bcrypt.genSalt( 10, function(err, salt) {
bcrypt.hash(nwtp, salt, function(err, hash) {
if (err) {
console.log(err);
return cb(err);
} else {
nwtp = hash;
console.log(nwtp);
return nwtp;
}
});
});
}
setPassword(nwtp);
console.log(nwtp);
console.log("3");
out put is
1
2
1234
3
$2a$10$kVmybMj7SsD5ip11lCU3AOFd4ZdKL6/0DzKADYcplIDx9qdZJAy/a
can i get it into that order..?
1
2
$2a$10$kVmybMj7SsD5ip11lCU3AOFd4ZdKL6/0DzKADYcplIDx9qdZJAy/a
3
$2a$10$kVmybMj7SsD5ip11lCU3AOFd4ZdKL6/0DzKADYcplIDx9qdZJAy/a

You should use async library https://github.com/caolan/async
Then, your code might look like this
var saltResult = null;
var hashResult = null;
async.series([
function(next) {
bcrypt.genSalt( 10, function(err, salt) {
saltResult = salt;
next(err);
});
},
function(next) {
bcrypt.hash(nwtp, saltResult, function(err, hash) {
hashResult = hash;
next(err);
});
}],
function(err) {
// your final processing here
}
);

Related

Mongodb.connect does not execute callback function

Im trying to connect to my Mongodb and insert some documents if they are not already in the db. It works fine with the first inserts but in the function existInDatabase it sometimes does not execute the callback function.
var MongoClient = require('mongodb').MongoClient;
var mongoData = require('./mongoData');
var exports = module.exports = {};
var dbName = 'checklist';
MongoClient.connect(mongoData.ConString, {
useNewUrlParser: true
}, function(err, db) {
if (err) throw err;
for (var key in mongoData.Customers) {
if (!existsInDatabase(mongoData.Customers[key], 'Customers')) {
db.db(dbName).collection('Customers').insertOne(mongoData.Customers[key], function(err, res) {
if (err) throw err;
console.log('1 document inserted');
db.close();
});
}
}
for (var key in mongoData.Categorys) {
if (!existsInDatabase(mongoData.Customers[key], 'Customers')) {
db.db(dbName).collection('Categorys').insertOne(mongoData.Categorys[key], function(err, res) {
if (err) throw err;
console.log('1 document inserted');
db.close();
});
}
}
});
function existsInDatabase(obj, collection) {
var result = false;
MongoClient.connect(mongoData.ConString, {
useNewUrlParser: true
}, function(err, db) {
db.db(dbName).collection(collection).find({}).forEach(function(doc) {
if (doc.id == obj.id) {
result = true;
}
}, function(err) {
console.log(err);
});
});
return result;
}
I have made a few changes to your code. It seems you are new to async programming, spend some time to understand the flow. Feel free for any further query. Here is your code.
// Welcome to aync programming
// Here no one waits for the slow processes
var MongoClient = require('mongodb').MongoClient;
var mongoData = require('./mongoData');
var exports = module.exports = {};
var dbName = 'checklist';
// Make the connection for once only
MongoClient.connect(mongoData.ConString, { useNewUrlParser: true },
function(err, db) {
if (err) throw err;
var myDB = db.db(dbName); // create DB for once
for (var key in mongoData.Customers) {
//make call to the function and wait for the response
existsInDatabase(mongoData.Customers[key], 'Customers', function(err, result) {
//once the response came excute the next step
if (result) {
myDB.collection('Customers').insertOne(mongoData.Customers[key], function(err, res) {
if (err) throw err;
console.log('1 document inserted');
});
}
});
}
for (var key in mongoData.Categorys) {
//make call to the function and wait for the response
existsInDatabase(mongoData.Customers[key], 'Customers', function(err, result) {
//once the response came excute the next step
if (result) {
myDB.collection('Categorys').insertOne(mongoData.Categorys[key], function(err, res) {
if (err) throw err;
console.log('1 document inserted');
});
}
});
}
// Both the for loop will work randomly without any order
function existsInDatabase(obj, collection, cb) {
var result = false;
myDB.collection(collection).findOne({ id: obj.id }, function(err, result)
{
if (err) {
//this cb will work only when db operation is complited
cb(err);
} else if (result) {
cb(null, true);
} else {
cb(null, false);
}
});
}
});
This code may result in some error. Feel free to ask more questions over it
db.db(dbName).collection(collection).find({}) returns a cursor per the docs. You are missing .toArray():
db.db(dbName).collection(collection).find({}).toArray()...

Finish execution if first query returns a value Node.js Express.js mongoDB

Before starting, please mind that i have been searching this over 2+ hours, the answer will be simple i know but i couldnt get it to work . i am new to express node mongodb,
MongoClient.connect(url, function(err, db) {
if (err) {
res.status(err.status); // or use err.statusCode instead
res.send(err.message);
}
var usernameGiven = req.body.usernameGiven;
//Select the database
var dbo = db.db("notifellow");
//run the query
var query = { username: usernameGiven , friends: []};
dbo.collection("users").findOne({ username: usernameGiven}, function(err, result) {
if (err){
res.status(err.status); // or use err.statusCode instead
res.send(err.message);
console.log("Query Error Occured!");
}
else {
if (result) {
//Send the response
res.send("EXISTS");
//I WOULD LIKE TO EXIT IF THIS LINE EXECUTES
}
}
});
dbo.collection("users").insertOne(query, function(err, result) {
if (err){
res.status(err.status); // or use err.statusCode instead
res.send(err.message);
console.log("Query Error Occured!");
}
else {
if (result) {
//Send the response
res.send("CREATED 201");
} else {
res.send("Failed to insert");
}
}
});
db.close();
});
my goal is to check if an user doesnt exists with given username, i would like to insert that to the DB.
i would like to exit if my query finds an match and arrange such that insertOne wont execute. please enlighten me!!
Once you are not using the async/await syntax you will have to nest the calls to MongoDB, so they execute in series. You can also use a module like async to achieve this.
MongoClient.connect(url, function(err, db) {
if (err) {
res.status(err.status); // or use err.statusCode instead
res.send(err.message);
}
var usernameGiven = req.body.usernameGiven;
//Select the database
var dbo = db.db("notifellow");
//run the query
var query = { username: usernameGiven , friends: []};
dbo.collection("users").findOne({ username: usernameGiven}, function(err, result) {
if (err){
res.status(err.status); // or use err.statusCode instead
db.close();
console.log("Query Error Occured!");
return res.send(err.message);
}
if (result) {
db.close();
return res.send("EXISTS");
}
dbo.collection("users").insertOne(query, function(err, result) {
if (err){
res.status(err.status); // or use err.statusCode instead
db.close();
console.log("Query Error Occured!");
return res.send(err.message);
}
db.close();
if (result) {
return res.send("CREATED 201");
}
res.send("Failed to insert");
});
});
});
Try this
dbo.collection("users").findOne({ username: usernameGiven}, function(err, result) {
if (err){
//put the error logic
}
else {
if (result) {
//Send the response
return result;
}
else{
// if above if block fails it means that user does not exist
//put the insert logic
}
});

mongoose password gets hashed twice

I am new to Mongoose and Node JS, and have this problem with password being hashed again after a user is updated.
Here is the code for hashing:
UserSchema.pre('save', function (next) {
var user = this;
bcrypt.hash(user.password, 10, function (err, hash) {
if (err) {
return next(err);
}
user.password = hash;
next();
})
});
and this is for updating the user
router.post('/insert', function (req, res) {
User.findById(req.session.userId, function (err, user) {
if (err) { throw err; }
if (user) {
user.patients = req.body.patients
user.diagnosis_list = req.body.diagnosis_list
user.medicine_dose_list = req.body.medicine_dose_list
user.medicine_list = req.body.medicine_list
user.save(function (err) {
if (err) throw err;
res.send(user.toJSON());
})
}
})
})
I understand that presave has to be prevented to be called on updating the user, I just have no clue how to do that. Is there some other way I can update the user without having presave being called maybe?
if (!user.isModified('password')) {
return next();
}
bcrypt.hash(user.password, 10, function (err, hash) {
if (err) {
return next(err);
}
user.password = hash;
next();
})
http://mongoosejs.com/docs/api.html#document_Document-isModified

crypto pbkdf2 is not called

I have written an function to hashpasswords with crypto.obkdf2. This function was working fine, but for some reason he doesn't anymore.
EDIT
In a controller I want to create an user with the user.service:
account.controller:
userService.createAccount(details, true, function(err, result){
if(err){
res.status(500).json({message: err});
}else{
//account is created, details are mailed, now we can set the user on the order
user = result;
}
})
The service does a few checks and call the user.register function
user.service
function createAccount (details, generatePassword, callback){
console.log("createAccount");
//generate password, save details + password, mail details, send results back in callback
//if(generatePassword){
// details.password = random(10);
//}
details.password = '7eb4f68ea4';
var userData = _.pick(details, 'firstName', 'lastNamePrefix', 'lastName','email','gender', 'password');
userData.verificationCode = random(8);
userData.userName = userData.email;
console.log("userdate", userData);
User.register(userData, function(err, user){
console.log("register user", err);
if(err && (11000 == err.code || 11001 == err.code)) {
console.log("E-mailadres already in use");
return callback("E-mailadres already in use");
}
if (err) {
console.log("Something went terribly wrong...", err);
return callback("Something went wrong: " + err)
}
var options = {
to: user.email,
subject: 'Uw account op Prisma Note',
template: 'new-account'
}
//Mail sturen met activatielink na aanmaken
mailService.mail(options, user, null, function(err, data){
console.log("sendmail!");
if (err) {
console.log("error sending mail", err);
return callback("Error sending mail: " + err.message);
}else{
console.log("hier!", user);
return callback(null, user);
}
});
})
}
The user.modal contains the register function:
user.model
User.statics.register = function(opts, callback) {
console.log("register!");
var self = this;
var data = _.cloneDeep(opts);
passwordService.hash(opts.password, function(err, hashedPassword, salt) {
if (err) {
console.log("passwordsrv", err);
return callback(err, null);
}
data.password = hashedPassword;
data.passwordSalt = salt;
self.model('User').create(data, function(err, user) {
if (err) {
console.log("createuser", err);
return callback(err, null);
}
user.password = undefined;
user.passwordSalt = undefined;
callback(err, user);
})
})
}
And finally, the code comes to the passwordService
password.service
var LEN = 256;
var SALT_LEN = 64;
var ITERATIONS = 10000;
var DIGEST = 'sha256';
function hashPassword(password, salt, callback){
console.log("hashPassword");
var len = LEN /2;
if (3 === arguments.length) {
crypto.pbkdf2(password, salt, ITERATIONS, len, DIGEST, function(err, derivedKey) {
if (err) {
console.log("crypto err", err);
return callback(err);
}
return callback(null, derivedKey.toString('hex'));
})
} else {
console.log("pwdsrv");
callback = salt;
crypto.randomBytes(SALT_LEN / 2, function(err, salt) {
if (err) {
console.log("randombyte", err);
return callback(err);
}
salt = salt.toString('hex');
console.log("hier");
console.log(password, salt, ITERATIONS, len, DIGEST);
//password = '7eb4f68ea4'
//salt = '21aaac28b8411326b8df5b8b60476904f58d40f972a2f5d698ec4d0fb57dc315'
//ITERATIONS = 10000
//len = 128
//DIGEST = 'sha256'
crypto.pbkdf2(password, salt, ITERATIONS, len, DIGEST, function(err, derivedKey) {
console.log("hjioo");
if (err) {
console.log("pbkdf2", err);
return callback(err);
}
console.log("hier");
callback(null, derivedKey.toString('hex'), salt);
})
})
}
}
This function is called from our 'user model'. That model has an User.statics.register function what we can call. After a lot of debugging lines I have found out the code stops at (in my tested cases) crypto.pbkdf2(password, salt, ITERATIONS, len, DIGEST, function(err, derivedKey) in the else of the function. The log before this function show the content of the variables, but I can't see the logs in the function.
I have no idea, why this is stopped working. We have updated our node.JS version, but since this is an node module, that must be no problem.
Can somebody help me to solve this problem, so our users can register again?
The mailservice, which you can see in the service, sends an email via Amazon SES, I think it is not relevant to post that code.

Save password hash only when password is present

I have a form where users can create a room with an optional password field. I want to save the password only if the password field contains something ( is not empty). I have hash middleware that hash the password before saving it to mongodb. Even if the password field is empty it is saving a hash value. I tried to add a condition to check if there is a value only then to proceed with the hashing but this does not seem to work.
Here is my post :
exports.postCreateRooms = function(req, res, next) {
req.assert('workspace', 'Please enter a board name').notEmpty();
var errors = req.validationErrors();
var enableVideo;
if (errors) {
req.flash('errors', errors);
return res.redirect('/dashboard');
}
var url = uuid.v4();
var room = new Room({
roomUrl: url,
roomName: req.body.workspace,
owner:req.user._id,
ownerEmail:req.user.email,
dateCreated: Date(),
lastUpdated: Date(),
users: [req.user._id]
});
if (req.body.password != ''){
room.password = req.body.password;
}
room.save(function(err) {
if (err) {
return next(err);
}
res.redirect('/board='+room.roomUrl);
});
};
here is my hash middleware :
roomSchema.pre('save', function(next) {
var room = this;
if(room.password){
bcrypt.genSalt(10, function(err, salt) {
if (err) {
return next(err);
}
bcrypt.hash(room.password, salt, null, function(err, hash) {
if (err) {
return next(err);
}
room.password = hash;
next();
});
});
}
});
What happens when you have the check in place?
From what I can see, you need a next() call outside of your if block in the middleware, so it knows to proceed even if there isn't a password specified.
It would look like
roomSchema.pre('save', function(next) {
var room = this;
if(room.password){
return bcrypt.genSalt(10, function(err, salt) {
if (err) {
return next(err);
}
bcrypt.hash(room.password, salt, null, function(err, hash) {
if (err) {
return next(err);
}
room.password = hash;
next();
});
});
}
next();
});

Resources