No callback error shown when using bcrypt-node - javascript

I am have created a node library file called encrypt.js.
Within that are some functions created using bcrypt-nodejs
var bcrypt = require('bcrypt-nodejs');
exports.cryptPassword = function(password, callback) {
bcrypt.genSalt(10, function(err, salt) {
if (err) return callback(err);
else {
bcrypt.hash(password, salt, function(err, hash) {
return callback(err, hash);
});
}
});
};
exports.comparePassword = function(password, userPassword, callback) {
bcrypt.compare(password, userPassword, function(err, isPasswordMatch) {
if (err) return callback(err);
else return callback(null, isPasswordMatch);
});
};
When I now use cryptPassword from my server.js file it shows an error coming from the bcrypt-nodejs library stating 'no callback function was given'
I have added a function within my call as below
var encryptedPassword = encrypt.cryptPassword(req.body.user.password, function (err, salt){
if(err) {throw err};
console.log('hlllll');
});
Can anyone help?

Syntax: bcrypt.hash(data, salt, progress, cb)
You must have two callbacks.
Document here:
https://npmjs.org/package/bcrypt-nodejs
Update:
You can use the package bcrypt instead of bcrypt-nodejs
And your code will work:
bcrypt.hash(password, salt, function(err, hash) {
return callback(err, hash);
});

You can actually use bcyrpt-nodejs if thats what you prefer,but you have to edit the following section in bCrypt.js
if(!callback) {
throw "No callback function was given."
}
and replace it with
if(typeof callback == 'undefined') {
callback = progress;
progress = null;
}
then in your code, just have this;
require('bcrypt').hash(values.password,null,null,function passwordEncrypted(err,password){

use bcyrpt.compareSync instead of bcypt.compare. It doesn't require a callback

Related

Problem hashing password with bcrypt on node.js

I have the code below. I'm trying to hash my admin password when they get registered. The password initially is set to default via the mongoose schema. Below are my codes. But it is not hashing.
AdminSchema.pre('save', function(next){
let admin = this; // bind this
if(admin.$isDefault('password')) {
bcrypt.genSalt(12, (err, salt)=> { // generate salt and harsh password
bcrypt.hash(admin.password, salt, (err, hash)=> {
admin.password = hash;
return next();
});
});
}
if(!admin.isModified('password')) {
return next();
}
bcrypt.genSalt(12, (err, salt)=> { // generate salt and harsh password
bcrypt.hash(admin.password, salt, (err, hash)=> {
admin.password = hash;
next();
});
});
});
It's because bcrypt method are execute asynchronously so for the first time this will be always executed
if(!admin.isModified('password')) {
return next();
}
this should work
AdminSchema.pre('save', function(next) {
const admin = this // bind this
if (admin.$isDefault('password') || admin.isModified('password')) {
bcrypt.genSalt(12, (err, salt) => { // generate salt and harsh password
if (err) {
return next(err);
}
bcrypt.hash(admin.password, salt, (err, hash) => {
if (err) {
return next(err);
}
admin.password = hash
return next()
})
})
} else {
return next();
}
})

pre() in es6 not running as expected?

Postman is returning error whenever i include this pre() function,
it returns an error else its working and everything is getting stored in db using mongodb.
Is there something wrong in ES6 format that i have used or any other?
Below is the code :
// userschema is the name of the schema //
// SALT_I = 10 //
userSchema.pre('save', next => {
if (this.isModified('password')) {
bcrypt.genSalt(SALT_I, (err, salt) => {
if (err)
return next(err)
bcrypt.hash(this.password, salt, (err, hash) => {
if (err)
return next(err)
this.password = hash
next()
})
})
} else
next()
})
here is the postman error:
{
"success": false,
"err": {}
}
and it is as i am making a post request using the function:
app.post('/api/users/register', (req, res) => {
const user = new User(req.body)
user.save((err, data) => {
if (err) return res.json({ success: false, err })
res.status(200).json({
success: true,
userdata: data
})
})
})
You cannot use ES6 spread operator but ES5 syntax works just fine:
userSchema.pre('save', function (next) {
const user = this
if (user.isModified('password')) {
bcrypt.genSalt(SALT_I, function (err, salt) {
if (err) {
console.log("inside gensalt if")
return next(err)
}
bcrypt.hash(user.password, salt, function (err, hash) {
if (err) {
console.log("inside bcrpt hash")
return next(err)
}
user.password = hash
next()
})
})
} else
next()
})

howto Node module.exports

I want to separate the code for executing mysql query in Node, so I am trying to use the Revealing Module pattern here
/* pool -create connection pool mysql*/
var sqlQuery = function (sqlString) {
var _result = pool.getConnection(function (err, connection) {
/* error handling*/
connection.query(sqlString, function (err, rows) {
console.log(this.sql);
if (!err) {
return _result = rows; <============
}
connection.release();
});
return;
});
console.log(_result);
return { recordSet : _result }
};
module.exports = sqlQuery;
How can I return rows to my app.js. the code below for calling sqlQuery is not working
var SqlQuery = require(./path/to/sqlQueryFile);
var rows = SqlQuery('pass sql here').recordSet;
console.log(row);
res.json(rows);
Your code is asynchronous, but you're calling it synchronously.
If you wanted to do it like this, you'll also need to pass a callback to SqlQuery.
/* pool -create connection pool mysql*/
var sqlQuery = function (sqlString, callback) {
var _result = pool.getConnection(function (err, connection) {
/* error handling*/
connection.query(sqlString, function (err, rows) {
console.log(this.sql);
if (!err) {
callback(rows);
}
connection.release();
});
});
};
module.exports = sqlQuery;
And then call it with:
var SqlQuery = require(./path/to/sqlQueryFile);
var rows = SqlQuery('pass sql here', function(recordSet){
console.log(recordSet);
res.json(recordSet);
});
Edit: If you're using newer versions of JavaScript, you have a few more options.
If you have access to Promises, you can do this:
function sqlQuery (sqlString) {
return new Promise((resolve, reject) => {
pool.getConnection(function (err, connection) {
if (err) { return reject(err); } // error handling
connection.query(sqlString, function (err, rows) {
if (err) { return reject(err); }
resolve(rows);
connection.release();
});
});
});
}
module.exports = sqlQuery;
And then you'd use it like:
var SqlQuery = require(./path/to/sqlQueryFile);
SqlQuery('pass sql here')
.then(function(recordSet) {
console.log(recordSet);
res.json(recordSet);
})
.catch(function(err) {
// do your error handling
res.status(500).json({ err: 'Sorry there was an error' });
});
If you're using even newer JavaScript, you can use the async/await syntax (currently available via Babel, and I think in FireFox. Chrome in V55).
var SqlQuery = require(./path/to/sqlQueryFile);
async handleQuery(query) {
try {
var rows = await SqlQuery(query);
res.json(rows);
} catch (e) {
console.log('Error!', e);
}
}
To chain multiple queries together:
async handleQuery(query) {
try {
return await SqlQuery(query);
} catch (e) {
console.log('Error!', e);
}
}
var rows = await handleQuery('select * from tablename');
var rowsToReturn = await handleQuery('select id from another_table where name = "' + rows[0].name + '"');

sqlite3 callbacks (node.js)

I'm trying to compare an entered email on my website, to ones in the database to see whether it already exists. If it does, then the function returns false and an error is displayed.
var db = new sqlite3.Database('users_db.db');
db.get(
"SELECT * FROM users WHERE useremail = ?",
[email],
function (err, rows) {
if (rows == undefined ){
global.returnvalue2 = false;
}
}
);
What I want is for the function to be run immediately after the selection, so that the returned value is false, and the user record is not created.
At the moment I realise that the callback is being called after everything, so its just making the selection and carrying on throughout the rest of the program until the end.
How can I check if there are any existing records with the same email?
Make use of the async features in javascript, so your code would look something like this;
var db = new sqlite3.Database('users_db.db');
function checkemail(email, cb) {
db.get(
"SELECT * FROM users WHERE useremail = ?",
[email],
function (err, rows) {
if (err || rows == undefined ){
cb("bad email", null)
} else {
cb(null,rows)
}
});
}
function checkpassword(pw,cb) {....}
function checkclass(cls,cb) {....}
and then write you code like this;
checkemail(myemail, function(err,rows) {
if (err) return alert(err);
checkpassword(pw, function(err, msg) {
if (err) return alert(err);
checkclass(cls, function(err, msg) {
if (err) return alert(err);
alert("Congratulation you passed all the checks");
});
});
});
Here's a little one I made.
const sqlite3 = require('sqlite3').verbose();
let db = new sqlite3.Database('iHacks.db');
function get_user_credentials (email, password)
{ return new Promise((rs, rj) => {
function callback (err, User)
{
if (err) rj(err);
rs(User);
}
db.get('select * from users where email=? and password=?', [email, password], callback);
}); }
function login (email, password)
{ return new Promise ((rs, rj) => {
// Hashing the password.
password = sha256(password + 'EzSalt');
// Creating an Error
const err = new Error('Email or password did not match!');
// Callback functions
function check (User)
{
rs(User);
}
function fail (err)
{
rj(err);
}
// Getting the user credentials
get_user_details(email, password).then(check).catch(fail);
}); }
login()
.then(/* Continue code */)
.catch(err => {throw new Error(err); })
;

No access to this from within nested callback

I have the following code:
var Company = function(app) {
this.crypto = require('ezcrypto').Crypto;
var Company = require('../models/company.js');
this.company = new Company(app);
}
// Create the company
Company.prototype.create = function (name, contact, email, password, callback) {
this.hashPassword(password, function(err, result) {
if (err) throw err;
console.log(this.company); // Undefined
this.company.create(name, contact, email, result.password, function(err, result) {
if (err) {
return callback(err);
}
return callback(null, result);
});
});
}
// Get company with just their email address
Company.prototype.hashPassword = function (password, callback) {
if(typeof password !== 'string') {
var err = 'Not a string.'
} else {
var result = {
password: this.crypto.SHA256(password)
};
}
if (err) {
return callback(err);
}
return callback(null, result);
}
module.exports = Company;
The problem is that this.company is undefined on line 11 of that code block.
I know this is not what I think, but I'm not sure how to refactor to get access to the correct this.
so theres 2 solution's to this
first the dirty one
Company.prototype.create = function (name, contact, email, password, callback) {
var that = this; // just capture this in the clojure <-
this.hashPassword(password, function(err, result) {
if (err) throw err;
console.log(that.company); // Undefined
that.company.create(name, contact, email, result.password, function(err, result) {
if (err) {
return callback(err);
}
return callback(null, result);
});
});
}
and the clean one using bind https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/bind
Company.prototype.create = function (name, contact, email, password, callback) {
this.hashPassword(password, (function(err, result) {
if (err) throw err;
console.log(this.company); // Undefined
this.company.create(name, contact, email, result.password, function(err, result) {
if (err) {
return callback(err);
}
return callback(null, result);
});
}).bind(this));
}
You can reference this through another variable by declaring it in the Company.create scope, like this:
// Create the company
Company.prototype.create = function (name, contact, email, password, callback) {
var me = this;
this.hashPassword(password, function(err, result) {
if (err) throw err;
console.log(me.company); // Undefined - not anymore
me.company.create(name, contact, email, result.password, function(err, result) {
if (err) {
return callback(err);
}
return callback(null, result);
});
});
}
Untested, but it should work like this.

Categories