encryption in node js - mysql

I tried to insert a encrypt value to db, i can encrypt the value the encrypted value can't be inserted in db.
app.post('/insert', function (req, res) {
// var Fname=req.body.fname;
// var Lname=req.body.pwd;
var data = {
Fname: req.body.fname,
Lname: req.body.Lname
};
function hashP(getit, cb) {
bcrypt.genSalt(15, function (err, salt) {
if (err) {
return console.log(err);
}
cb(salt);
bcrypt.hash(getit, salt, function (err, gotit) {
if (err) throw err;
return this.cb(null, gotit);
})
})
}
hashP(data.Lname, function (err, gotit) {
if (err) throw err;
data.Lname = hash;
})
console.log(data.Lname);
con.query("insert into test set ?", [data], function (err, rows) {
if (err) throw err;
res.send("Value has bee inserted");
})
})
This is my html form page:
<body>
<form action="http://localhost:8888/insert" method="POST" >
<label>Name:</label><input type="text" name="fname"></br>
<label>Lname:</label><input type="text" name="Lname"></br>
<button type="submit">Submit</button>
</form>
</body>

Seems like your function hashP(getit,cb) is calling cb function at bad time isn't it? try the following
function hashP(getit, cb){
bcrypt.genSalt(15, function (err, salt){
if(err) {
return cb(err, null);
}
bcrypt.hash(getit, salt, function (err, hash){
if(err) {
return cb(err, null);
}
return cb(null, hash);
})
})
}
Apart, you'll need to call it inside your handler as following:
app.post(...., function(req, res) {
var data = { ... }
function hashP(data, cb){ ... }
hashP(data.Lname, function (err, hash) {
if (err) throw err;
data.Lname = hash;
// NOW, SAVE THE VALUE AT DB
con.query("insert into test set ?", [data], function (err, rows) {
if (err) throw err;
res.send("Value has bee inserted");
})
}
}
The problem here was asynchronous execution, you were calling con.query with data before data is returned from hashP

Related

Connect to MySql in node.js project with mvc architecture

I have a node.js project with mvc architectures,
I am trying to connect it to mysql database, and write a query,
I get the query result, but when I try to call the function that declare the query, I get an empty result,
I guess so it because of the query calling is async.
in my model:
exports.getAllUsers = function () {
con.connect(function (err) {
if (err)
console.log('error')
else
con.query("SELECT * FROM Users", function (err, result, fields) {
if (err) throw err;
else {
return result;
}
});
});
}
in my controller:
exports.get_all_users = function (req, res) {
var arr = UserModel.getAllUsers();
res.send(arr);
}
the arr in get_all_users function is always undefined,
what can be the problem???
There are three options you could use in node.js.
These are simple code for demo three style, they still have a lot space for improvement.
callback style
exports.getAllUsers = function (callback) {
con.connect(function (err) {
if (err)
console.log('error')
else
con.query("SELECT * FROM Users", function (err, result, fields) {
if (err) throw err;
else {
callback(result);
}
});
});
}
exports.get_all_users = function (req, res) {
UserModel.getAllUsers((result) => {
res.send(result);
});
}
promise style
exports.getAllUsers = function () {
return new Promise((resolve, reject) => {
con.connect(function (err) {
if (err)
console.log('error')
else
con.query("SELECT * FROM Users", function (err, result, fields) {
if (err) throw err;
else {
resolve(result);
}
});
});
})
}
exports.get_all_users = function (req, res) {
UserModel.getAllUsers().then(result) => {
res.send(result);
});
}
async-await style
promise style
exports.getAllUsers = function () {
return new Promise((resolve, reject) => {
con.connect(function (err) {
if (err)
console.log('error')
else
con.query("SELECT * FROM Users", function (err, result, fields) {
if (err) throw err;
else {
resolve(result);
}
});
});
})
}
exports.get_all_users = async function (req, res) {
const result = await UserModel.getAllUsers();
res.send(result);
}

how to return mysql query and an object

I need to return the MySQL query and an object from a function
when I try this code it works
const executeScript = (id, usersData, result) => {
db.query(`UPDATE users SET ? WHERE users_id=${id}`, usersData, (err, res) => {
if (err) {
result(null, err);
} else {
result(null, res);
}
});
};
executeScript(update(id, usersData), (err, results) => {
if (err) res.send(err);
res.json(results);
});
I need to use this format because of these functions is in different files
const update = (id, usersData) => {
return `UPDATE users SET ? WHERE users_id=${id}`, usersData;
};
const executeScript = (query, result) => {
db.query(query, (err, res) => {
if (err) {
result(null, err);
} else {
result(null, res);
}
});
};
executeScript(update(id, usersData), (err, results) => {
if (err) res.send(err);
res.json(results);
});

MySQL user-defined variables in Node.js mysql module

I was wondering whether MySQL user-defined variables will work using Node.js mysql module. The example below highlight exactly what I want to achieve using a transaction:
connection.beginTransaction(err => {
if (err) { throw err; }
connection.query('INSERT INTO user SET = ?', {id: 12, username: 'name'}, (err, results) => {
if (err) {
return connection.rollback(function() {
throw error;
});
}
connection.query('SELECT #user_id:=userID FROM user WHERE username = ?', ['name'], (err, results) => {
if (err) {
return connection.rollback(function() {
throw error;
});
}
connection.query('INSERT INTO authentication SET `userID` = #user_id, ?', {password: 'userpassword'}, (err, results) => {
if (err) {
return connection.rollback(function() {
throw error;
});
}
connection.commit(err => {
if (err) {
return connection.rollback(function() {
throw err;
});
}
console.log('success!');
});
});
});
});
});
You might be wondering, why not use the result of the second query in the third query. The transaction function is wrapped inside a utility function that accepts queries as an argument to be executed using transaction.
If the above code sample doesn't work, please is there a concise way to achieve this. Thank you.
After running the code sample it failed not because of MySQL variable in the second query. This code sample is what works for me:
connection.beginTransaction(err => {
if (err) { throw err; }
connection.query('INSERT INTO user (id, username) VALUES(?, ?)', [12, 'name'], (err, results) => {
if (err) {
return connection.rollback(function() {
throw error;
});
}
connection.query('SELECT #user_id:=userID FROM user WHERE username = ?', ['name'], (err, results) => {
if (err) {
return connection.rollback(function() {
throw error;
});
}
connection.query('INSERT INTO authentication (id, password) VALUES (#user_id, ?), ['userpassword'], (err, results) => {
if (err) {
return connection.rollback(function() {
throw error;
});
}
connection.commit(err => {
if (err) {
return connection.rollback(function() {
throw err;
});
}
console.log('success!');
});
});
});
});
});

Node JS Inserting array of objects to mysql database when using transactions

Am using node-mysql to add records to a database but am facing a challenge when the records to be inserted are an array of objects and I need the operation to be a transaction. I have simplified my problem by creating a test project to better explain my problem.
Lets say I have to tables users and orders and the data to be inserted looks like this
var user = {
name: "Dennis Wanyonyi",
email: "example#email.com"
};
var orders = [{
order_date: new Date(),
price: 14.99
}, {
order_date: new Date(),
price: 39.99
}];
I want to first insert a user to the database and use the insertId to add the each of the orders for that user. Am using a transaction since in case of an error, I want to rollback the whole process. Here is how I try to insert all the records using node-mysql transactions.
connection.beginTransaction(function(err) {
if (err) { throw err; }
connection.query('INSERT INTO users SET ?', user, function(err, result) {
if (err) {
return connection.rollback(function() {
throw err;
});
}
for (var i = 0; i < orders.length; i++) {
orders[i].user_id = result.insertId;
connection.query('INSERT INTO orders SET ?', orders[i], function(err, result2) {
if (err) {
return connection.rollback(function() {
throw err;
});
}
connection.commit(function(err) {
if (err) {
return connection.rollback(function() {
throw err;
});
}
console.log('success!');
});
});
}
});
});
However I have a problem iterating over the array of orders without having to call connection.commit multiple times within the for loop
I would suggest to construct a simple string for multiple row insert query for orders table in the for loop first and then execute it outside the for loop. Use the for loop to only construct the string. So you can rollback the query whenever you want or on error. By multiple insert query string i mean as follows:
INSERT INTO your_table_name
(column1,column2,column3)
VALUES
(1,2,3),
(4,5,6),
(7,8,9);
You can use Promise.all functionality of Bluebird for this.
var promiseArray = dataArray.map(function(data){
return new BluebirdPromise(function(resolve, reject){
connection.insertData(function(error, response){
if(error) reject(error);
else resolve(response);
}); //This is obviously a mock
});
});
And after this:
BluebirdPromise.all(promiseArray).then(function(result){
//result will be the array of "response"s from resolve(response);
database.commit();
});
This way, you can work all the inserts asyncronously and then use database.commit() only once.
Some kind of task in Node.js are Asynchronous( like I/O , DB and etc..), and there is a lots of LIBS that help to handle it.
but if you want don't use any lib,for iterating an array in JS and use it in an asynchronous functionality its better to implement it as recursive function.
connection.beginTransaction(function(err) {
if (err) {
throw err;
}
connection.query('INSERT INTO users SET ?', user, function(err, result) {
if (err) {
return connection.rollback(function() {
throw err;
});
}
// console.log(result.insertId) --> do any thing if need with inserted ID
var insertOrder = function(nextId) {
console.log(nextId);
if ((orders.length - 1) < nextId) {
connection.commit(function(err) {
if (err) {
return connection.rollback(function() {
throw err;
})
}
console.log(" ok");
});
} else {
console.log(orders[nextId]);
connection.query('INSERT INTO orders SET ?', orders[nextId], function(err, result2) {
if (err) {
return connection.rollback(function() {
throw err;
});
}
insertOrder(nextId + 1);
});
}
}
insertOrder(0);
});
});
as you can see I rewrite your for loop as a recursive function inside.
I would use the async.each to do the iteration and to fire all the queries in parallel. If some of the queries will fail, the asyncCallback will be called with an error and the program will stop processing the queries. This will indicate that we should stop executing queries and rollback. If there is no error we can call the commit.
I' ve decoupled the code a bit more and split it into functions:
function rollback(connection, err) {
connection.rollback(function () {
throw err;
});
}
function commit(connection) {
connection.commit(function (err) {
if (err) {
rollback(connection, err);
}
console.log('success!');
});
}
function insertUser(user, callback) {
connection.query('INSERT INTO users SET ?', user, function (err, result) {
return callback(err, result);
});
}
function insertOrders(orders, userId, callback) {
async.each(orders, function (order, asyncCallback) {
order.user_id = userId;
connection.query('INSERT INTO orders SET ?', order, function (err, data) {
return asyncCallback(err, data);
});
}, function (err) {
if (err) {
// One of the iterations above produced an error.
// All processing will stop and we have to rollback.
return callback(err);
}
// Return without errors
return callback();
});
}
connection.beginTransaction(function (err) {
if (err) {
throw err;
}
insertUser(user, function (err, result) {
if (err) {
rollback(connection, err);
}
insertOrders(orders, result.insertId, function (err, data) {
if (err) {
rollback(connection, err);
} else {
commit(connection);
}
});
});
});
you need to use async library for these kind of operation.
connection.beginTransaction(function(err) {
if (err) { throw err; }
async.waterfall([
function(cb){
createUser(userDetail, function(err, data){
if(err) return cb(err);
cb(null, data.userId);
});
},
function(userid,cb){
createOrderForUser(userid,orders, function() {
if(err) return cb(err);
cb(null);
});
}
], function(err){
if (err)
retrun connection.rollback(function() {
throw err;
});
connection.commit(function(err) {
if (err) {
return connection.rollback(function() {
throw err;
});
}
console.log('success!');
});
});
});
var createUser = function(userdetail, cb){
//-- Creation of Orders
};
var createOrderForUser = function (userId, orders, cb) {
async.each(orders, function(order, callback){
//-- create orders for users
},function(err){
// doing err checking.
cb();
});
};
See if you can write a Stored Procedure to encapsulate the queries, and have START TRANSACTION ... COMMIT in the SP.
The tricky part comes with needing to pass a list of things into the SP, since there is no "array" mechanism. One way to achieve this is to have a commalist (or use some other delimiter), then use a loop to pick apart the list.
currentLogs = [
{ socket_id: 'Server', message: 'Socketio online', data: 'Port 3333', logged: '2014-05-14 14:41:11' },
{ socket_id: 'Server', message: 'Waiting for Pi to connect...', data: 'Port: 8082', logged: '2014-05-14 14:41:11' }
];
console.warn(currentLogs.map(logs=>[ logs.socket_id , logs.message , logs.data , logs.logged ]));

Nodejs with Mysql Database Return value

I have the following code. I am relative new to nodejs &js
I want to get values in 1. log but i get undefined.
Only 2. log is outputed to the log.
I read nodeJS return value from callback and
https://github.com/felixge/node-mysql but there is no example about return value.
I donot know how to use return statement with the given example in node-mysql page.
exports.location_internal = function (req, res) {
var r = getExternalLocation(2);
// 1. log
console.log(r);
res.send( r);
}
var getExternalLocation = function (id) {
pool.getConnection(function(err, connection){
if(err) throw err;
var response = {};
connection.query( "select * from external_geo_units where geo_unit_id = "+id, function(err, rows){
if(err) throw err;
response.data= rows;
// 2. log
console.log(response);
return response;
});
connection.release();
});
};
It's asynchronous, so you have to pass in a callback to get the value when it's ready. Example:
exports.location_internal = function(req, res, next) {
getExternalLocation(2, function(err, rows) {
if (err)
return next(err);
console.log(rows);
res.send(rows);
});
};
function getExternalLocation(id, cb) {
pool.getConnection(function(err, conn) {
if (err)
return cb(err);
conn.query("select * from external_geo_units where geo_unit_id = ?",
[id],
function(err, rows) {
conn.release();
cb(err, rows);
});
});
}