Node js - Done is not a function after insertion in database - mysql

Im trying for the first time to do an authentification in node js. THe insertion in database is working but i've got an issue about the done function and i dont understand why. It's surely a simply answer but im still a beginner in node. Im using express and passeport for the authentification.
My code :
// DB
var LocalStrategy = require("passport- local").Strategy;
var mysql = require('mysql');
var bcrypt = require('bcrypt-nodejs');
var dbconfig = require('./database');
var connection = mysql.createConnection(dbconfig.connection);
// BD PASSEPORT
connection.query('USE ' + dbconfig.database);
module.exports = function (passport) {
passport.serializeUser(function (user, done) {
done(null, user.id);
});
passport.deserializeUser(function (id, done) {
connection.query("SELECT * FROM client WHERE id = ? ", [id],
function (err, rows) {
done(err, rows[0]);
});
});
passport.use(
'local-signup',
new LocalStrategy({
usernameField: 'username',
mailField: 'mail',
passwordField: 'password',
passReqToCallback: true
},
function (req, username, mail, password, done) {
connection.query("SELECT * FROM client WHERE username = ? ",
[username], function (err, rows) {
if (err)
return done(err);
if (rows.length) {
return done(null, false, req.flash('signupMessage', 'That is already taken'));
} else {
var newUserMysql = {
username: username,
mail: mail,
password: bcrypt.hashSync(password, null, null)
};
var insertQuery = "INSERT INTO client (username, mail, password) values (?, ?, ?)";
connection.query(insertQuery, [newUserMysql.username, newUserMysql.mail, newUserMysql.password],
function (err, rows) {
newUserMysql.id = rows.insertId;
console.log(newUserMysql);
return done(null, newUserMysql);
});
}
});
})
);
the problem is the last done funciton :
The output
{
username: 'eazeazea',
mail: 'eazeazeaze',
password: '$2a$10$iUOYeqzQqV6hJ.WvYMom8uesUxxtKpKfdb8GcoJ4Chkv ka.FIZfiO',
id: 20
}
D:\Projets\group-780053\node_modules\mysql \lib\protocol\Parser.js:437
throw err; // Rethrow non-MySQL errors
^
TypeError: done is not a function
at Query.<anonymous> (D:\Projets\group-780053 \config\passport.js:51:44)
at Query.<anonymous> (D:\Projets\group-780053 \node_modules\mysql\lib\Connection.js:526:10)
at Query._callback (D:\Projets\group-780053\node_modules\mysql\lib\Connection.js:488:16)
at Query.Sequence.end (D:\Projets\group-780053\node_modules\mysql\lib\protocol\sequences\Sequence.js:83:24)
at Query._handleFinalResultPacket (D:\Projets\group-780053\node_modules\mysql\lib\protocol\sequences\Query.js:149:8)
at Query.OkPacket (D:\Projets\group-780053\node_modules\mysql\lib\protocol\sequences\Query.js:74:10)
at Protocol._parsePacket (D:\Projets\group-780053\node_modules\mysql\lib\protocol\Protocol.js:291:23)
at Parser._parsePacket (D:\Projets\group-780053\node_modules\mysql\lib\protocol\Parser.js:433:10)
at Parser.write (D:\Projets\group-780053\node_modules\mysql\lib\protocol\Parser.js:43:10)
at Protocol.write (D:\Projets\group-780053\node_modules\mysql\lib\protocol\Protocol.js:38:16)
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! node-loginregister# start: `node ./server`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the node-loginregister# start script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm ERR! A complete log of this run can be found in:
npm ERR! C:\Users\Nicol\AppData\Roaming\npm-cache\_logs\2020-07-16T10_30_48_382Z-debug.log

The passport.use when is use to rename the strategie the signature, is like this
passport.use('new-name', new LocalStrategy(options, (req, email, password, done) => {
// ....
}))
To be more specific to your example It should look like this.
passport.use('local-signup', new LocalStrategy({
usernameField: 'username',
passwordField: 'password',
passReqToCallback: true
}, function((req, email, password, next) {
// ...
})));
But in your case you passed 5 parameters, and the parameter which is named done in your case is the fifth parameter.
When passport will call that method function which is the verify as named in the code of passport-local sources
it will be passed only 4 parameters and they won't be any fifty parameter, so it will be undefined.
Your code just means you are trying to pass parameter to undefined which will obviously through an error. to fix that you will make this changes
replace this line
function (req, username, mail, password, done) { }
with
function (req, email, password, done) { }

Related

Nodejs Mysql query throw err

I try to register my user into a mysql database but an error appears
I checked my database and the user is added but the error is still here.
The Error :
throw err; // Rethrow non-MySQL errors
My code :
create : function(body, callback)
{
var bind = [];
for(prop in body) {
bind.push(body[prop]);
}
let sql = `INSERT INTO users(email, firstname, lastname, password, language, currency, seed) VALUES (?, ?, ?, ?, ?, ?, ?)`;
pool.query(sql, bind, function(err, lastId) {
if(err) throw err
callback(lastId);
});
}
pool.js
const util = require('util');
const mysql = require('mysql');
const pool = mysql.createPool({
connectionLimit: 10,
host: '**',
user: '**',
password: '**',
database: '***'
});
pool.getConnection((err, connection) => {
if(err)
{
console.error("Something went wrong connecting to the database.");
}
if(connection) {
connection.release();
}
return;
});
pool.query = util.promisify(pool.query);
module.exports = pool;
I think there's a few solutions you can try here.
In your pool.js file, just export pool.query and not the promisified version
Surround your call to pool.query in the create() function with a promise and resolve the promise with the lastId variable instead of using a callback
Use npm mysql2 as it comes with a promise wrapper: https://www.npmjs.com/package/mysql2#using-promise-wrapper
Hope that helps!

Error: Packets out of order. Got: 1 Expected: 0

All the Solutions I found for this Problem don't work for me.
I'm just loading one Dataset and after approximate 150 Request I get this Error:
Error: Packets out of order. Got: 1 Expected: 0
at Parser._tryReadPacketHeader (C:\dev\node\webkoll\node_modules\mysql\lib\protocol\Parser.js:470:15)
at Parser.write (C:\dev\node\webkoll\node_modules\mysql\lib\protocol\Parser.js:33:29)
at Protocol.write (C:\dev\node\webkoll\node_modules\mysql\lib\protocol\Protocol.js:38:16)
at Socket.<anonymous> (C:\dev\node\webkoll\node_modules\mysql\lib\Connection.js:88:28)
at Socket.<anonymous> (C:\dev\node\webkoll\node_modules\mysql\lib\Connection.js:526:10)
at Socket.emit (events.js:223:5)
at addChunk (_stream_readable.js:309:12)
at readableAddChunk (_stream_readable.js:290:11)
at Socket.Readable.push (_stream_readable.js:224:10)
at TCP.onStreamRead (internal/stream_base_commons.js:181:23)
--------------------
at Protocol._enqueue (C:\dev\node\webkoll\node_modules\mysql\lib\protocol\Protocol.js:144:48)
at Protocol.handshake (C:\dev\node\webkoll\node_modules\mysql\lib\protocol\Protocol.js:51:23)
at PoolConnection.connect (C:\dev\node\webkoll\node_modules\mysql\lib\Connection.js:116:18)
at Pool.getConnection (C:\dev\node\webkoll\node_modules\mysql\lib\Pool.js:48:16)
at C:\dev\node\webkoll\dbHelper.js:35:22
at new Promise (<anonymous>)
at dbHelper.execQueryWithParams (C:\dev\node\webkoll\dbHelper.js:34:16)
at dbHelper.loadFinishedResultFlag (C:\dev\node\webkoll\dbHelper.js:68:21)
at C:\dev\node\webkoll\index.js:321:30
at Layer.handle [as handle_request] (C:\dev\node\webkoll\node_modules\express\lib\router\layer.js:95:5) { code: PROTOCOL_PACKETS_OUT_OF_ORDER', fatal: true}
I'm using node v12.14.1 and the npm package mysql v2.18.1.
I also set the max_allowed_packet to 1G but it did not help.
Here the Code i use to get the data:
class dbHelper {
constructor() {
const { host, user, password, database, connectionLimit } = config.db;
this.con = mysql.createPool({
connectionLimit,
host,
user,
password,
database
});
}
async execQueryWithParams(query, params) {
return new Promise((resolve, reject) => {
this.con.getConnection((err, connect) => {
if (err) {
console.log(err);
return reject(err)
}
connect.query(query, [params], (err, result) => {
if (err) {
return reject(err);
}
resolve(result);
})
})
});
}
I found the Problem.
After using the npm package mysql2 I got the error message: "Too many connections".
I dumbly initialized my class way to often, so after using just one instance everything worked fine.
Try to increase the MAX_Packet_Allowed Memory - it works in my case
It can be - your pool connection is lost. Try checking wether it is still up.
You are doing some minor mistake for define variable and function definition on proper ways..
const mysql = require('mysql');
const con = mysql.createConnection({
host : process.env.RDS_HOSTNAME,
user : process.env.RDS_USERNAME,
password : process.env.RDS_PASSWORD,
port : process.env.RDS_PORT,
database : process.env.RDS_DATABASE
});
exports.handler = (event, context, callback) => {
// allows for using callbacks as finish/error-handlers
context.callbackWaitsForEmptyEventLoop = false;
const sql = "select * from user_status";
con.query(sql, function (err, result) {
if (err) throw err;
console.log(result);
callback(null, result)
});
};
I am using the above code and now I m getting data from my RDS.🙂🙂
Note: you need to define your mysql credentials for host,user,password,port,database.

How to fix : " Error: data and hash arguments required "

I'm trying login with a user that I have registered in my form but I have this error:
Error: data and hash arguments required
The user is registered in my database with a Username, Fullname and the hashed password thanks to bcrypt.
const pool = require("./pool");
const bcrypt = require("bcrypt");
function User() {}
User.prototype = {
find: function(user = null, callback) {
if (user) {
var field = Number.isInteger(user) ? "id" : "username";
}
let sql = `SELECT * FROM users WHERE ${"" + field + ""} = ?`;
pool.query(sql, user, function(err, result) {
if (err) console.log(err);
callback(result);
});
},
create: function(body, callback) {
let pwd = body.password;
body.password = bcrypt.hashSync(pwd, 10);
var bind = [body.username, body.fullname, body.password];
console.log(bind);
let sql =
"INSERT INTO users(username, fullname, password) VALUES (?, ?, ?)";
pool.query(sql, bind, function(err, lastId) {
if (err) throw err;
callback(lastId);
});
},
login: function(username, password, callback) {
this.find(username, function(user) {
if (user) {
if (bcrypt.compareSync(password, user.password)) {
callback(user);
return;
}
}
});
}
};
module.exports = User;
Once i press my login button in my form this is the error I'm getting
throw err; // Rethrow non-MySQL errors
^
at Object.compareSync (/Users/me/happy/node_modules/bcrypt/bcrypt.js:167:15)
at /Users/me/happy/core/user.js:46:20
at Query.<anonymous> (/Users/me/happy/core/user.js:16:7)
at Query.<anonymous> (/Users/me/happy/node_modules/mysql/lib/Connection.js:525:10)
at Query._callback (/Users/me/happy/node_modules/mysql/lib/Connection.js:491:16)
at Query.Sequence.end (/Users/me/happy/node_modules/mysql/lib/protocol/sequences/Sequence.js:83:24)
at Query._handleFinalResultPacket (/Users/me/happy/node_modules/mysql/lib/protocol/sequences/Query.js:139:8)
at Query.EofPacket (/Users/me/happy/node_modules/mysql/lib/protocol/sequences/Query.js:123:8)
at Protocol._parsePacket (/Users/me/happy/node_modules/mysql/lib/protocol/Protocol.js:291:23)
at Parser._parsePacket (/Users/me/happy/node_modules/mysql/lib/protocol/Parser.js:433:10)
Make sure you are passing valid values in both arguments. userpassword and dbpassword should not be undefined or null
Try to generate a salt synchronously, updating this line
body.password = bcrypt.hashSync(pwd, 10);
for
body.password = bcrypt.hashSync(pwd, bcrypt.genSaltSync(10));
Please check password and user.password is not equal to undefined. Because the same function is working fine for me.
If you are still facing the same issue then please try bcrypt.compare. bcrypt.compare takes 3 parameters passwordToCheck, passwordHash and a callback.
login: function(username, password, callback) {
this.find(username, function(user) {
if (user) {
bcrypt.compare(password, user.password, function(err, match) {
if (err) throw new Error(err);
else if (match == false) {
return res.json({
success: false,
message: 'Wrong Password'
})
} else {
callback(user);
return;
}
});
}
});
};

TypeError: Cannot read property 'password' of undefined in login route

When i'm requesting the api with the email which does not exist in the mysql DB it throws a error but in the opposite condition it runs.
Error:
S:\#development\Pepperkart\pepperkart-backend\node_modules\mysql\lib\protocol\Parser.js:437
throw err; // Rethrow non-MySQL errors
^
TypeError: Cannot read property 'password' of undefined
at Query.db.query (S:\#development\Pepperkart\pepperkart-backend\routes\users.js:19:43)
at Query.<anonymous> (S:\#development\Pepperkart\pepperkart-backend\node_modules\mysql\lib\Connection.js:525:10)
at Query._callback (S:\#development\Pepperkart\pepperkart-backend\node_modules\mysql\lib\Connection.js:491:16)
at Query.Sequence.end (S:\#development\Pepperkart\pepperkart-backend\node_modules\mysql\lib\protocol\sequences\Sequence.js:83:24)
at Query._handleFinalResultPacket (S:\#development\Pepperkart\pepperkart-backend\node_modules\mysql\lib\protocol\sequences\Query.js:139:8)
at Query.EofPacket (S:\#development\Pepperkart\pepperkart-backend\node_modules\mysql\lib\protocol\sequences\Query.js:123:8)
at Protocol._parsePacket (S:\#development\Pepperkart\pepperkart-backend\node_modules\mysql\lib\protocol\Protocol.js:291:23)
at Parser._parsePacket (S:\#development\Pepperkart\pepperkart-backend\node_modules\mysql\lib\protocol\Parser.js:433:10)
at Parser.write (S:\#development\Pepperkart\pepperkart-backend\node_modules\mysql\lib\protocol\Parser.js:43:10)
at Protocol.write (S:\#development\Pepperkart\pepperkart-backend\node_modules\mysql\lib\protocol\Protocol.js:38:16)
[nodemon] app crashed - waiting for file changes before starting...
My api looks like this:
router.post('/login', (req, res) => {
var email = req.body.email
var password = req.body.password
var GRAB_USER = `SELECT * FROM user_details WHERE email = ?`
db.query(GRAB_USER, email, (err, result) => {
if (err) {
res.send('email not found')
} else {
var user = result[0]
bcrypt.compare(password, user.password, (err, match) => {
if (err) {
res.send('password not match')
} else {
res.send(user)
}
});
}
})
})
your query is fine and not giving error so you should also check result.length> 0 and then res.send('email not found')
router.post('/login', (req, res) => {
var email = req.body.email
var password = req.body.password
var GRAB_USER = `SELECT * FROM user_details WHERE email = ?`
db.query(GRAB_USER, email, (err, result) => {
if (err) {
res.send('email not found')
}
else if (result.length==0) {
res.send('email not found') //this is what you are missing
}
else {
var user = result[0]
bcrypt.compare(password, user.password, (err, match) => {
if (err) {
res.send('password not match')
} else {
res.send(user)
}
});
}
})
})
after the following line of code, I would recommend to add a console statement and see what are you getting in user because your user is undefined here
var user = result[0]
console.log(user)
and see the result if the user is undefined and add a console for result and see what are you getting in result then assign the value in user

passport-local with mysql not working

I am using node.js and passport and mysql for a userlogin.
I the main source is from https://github.com/manjeshpv/node-express-passport-mysql/issues
I want to add more columns in the table. I started with emailfield and change the code like below. I simply added the email variable at the needed places I think. I cannot find the bug where its crashing. without modifying anything, the code does work.
passport.js:
passport.use(
'local-signup',
new LocalStrategy({
// by default, local strategy uses username and password, we will override with email
usernameField : 'username',
passwordField : 'password',
//emailField : 'email',
passReqToCallback : true // allows us to pass back the entire request to the callback
},
function(req, username, password, email, done) {
// find a user whose email is the same as the forms email
// we are checking to see if the user trying to login already exists
connection.query("SELECT * FROM users WHERE username = ?",[username], function(err, rows) {
if (err)
log.info(err);
//return done(err);
if (rows.length) {
return done(null, false, req.flash('signupMessage', 'That username is already taken.'));
} else {
// if there is no user with that username
// create the user
var newUserMysql = {
username: username,
email: email,
password: bcrypt.hashSync(password, null, null) // use the generateHash function in our user model
};
var insertQuery = "INSERT INTO users ( username, password, email ) values (?,?,?)";
connection.query(insertQuery,[newUserMysql.username, newUserMysql.password, newUserMysql.email],function(err, rows) {
newUserMysql.id = rows.insertId;
return done(null, newUserMysql);
});
}
});
})
);
and here the log:
The magic happens on port 8080
GET /signup 200 20ms - 1.21kb
D:\node-express-passport-mysql\node_modules\mysql\lib\protocol\Parser.js:82
throw err;
^
TypeError: undefined is not a function
at Object.SqlString.escape (D:\node-express-passport-mysql\node_modules\mysq
l\lib\protocol\SqlString.js:46:13)
at D:\node-express-passport-mysql\node_modules\mysql\lib\protocol\SqlString.
js:80:19
at String.replace (native)
at Object.SqlString.format (D:\node-express-passport-mysql\node_modules\mysq
l\lib\protocol\SqlString.js:71:14)
at Connection.format (D:\node-express-passport-mysql\node_modules\mysql\lib\
Connection.js:263:20)
at Connection.query (D:\node-express-passport-mysql\node_modules\mysql\lib\C
onnection.js:196:22)
at Query._callback (D:\node-express-passport-mysql\config\passport.js:71:32)
at Query.Sequence.end (D:\node-express-passport-mysql\node_modules\mysql\lib
\protocol\sequences\Sequence.js:96:24)
at Query._handleFinalResultPacket (D:\node-express-passport-mysql\node_modul
es\mysql\lib\protocol\sequences\Query.js:144:8)
at Query.EofPacket (D:\node-express-passport-mysql\node_modules\mysql\lib\pr
otocol\sequences\Query.js:128:8)
28 Jun 21:03:58 - [nodemon] app crashed - waiting for file changes before starti
ng...
This looks to be the problem:
function(req, username, password, email, done) {
You added an extra argument email which shouldn't be there. Since it clobbers the done callback, when your code tries to call it it will cause an "undefined is not a function" error.
If you're passing an extra email property, you can access it through req.body.email (assuming that you're using a POST route to log in).