MYSQL length of results undefined - mysql

*throw err; // Rethrow non-MySQL errors
^
TypeError: Cannot read property 'length' of undefined*
db.js:
function validateUser(username, password) {
var sql = "SELECT * FROM users WHERE username = ? AND password = ?";
var values = [[username, password]];
con.query(sql,[values], function(err, results) {
if (results.length > 0){
return true;
}
else return false;
})
}
server.js:
app.post('/auth', function(req,res) {
console.log('form submitted');
if(db.validateUser(req.body.username,req.body.password)){
console.log('login successful');
}
res.status(200);
res.redirect(URL);
});

First please don't save passswords as plain text.
for example https://cdnjs.com/libraries/jsSHA
For your code:
function validateUser(username, password) {
var sql = "SELECT * FROM users WHERE username = ? AND password = ?";
var values = [username, password];
con.query(sql,values, function(err, results) {
if (results.length > 0){
return true;
}
else return false;
})
}

Related

custom mysql function in nodejs returns undefined

so I have a multi function in a file in NodeJS, and it returns undefined, so here is my code:
`
var MySql = require('mysql');
var mysql = MySql.createConnection({
host: process.env.DB_IP,
user: process.env.DB_USER,
password: process.env.DB_PASS,
database: "gamezone_3tar"
});
mysql.connect(function(err){
if (err) throw err;
console.log('MySql Connection Successfully!');
});
module.exports = {
checkGuild: function(gid){
var sql = "SELECT * FROM GUILDS WHERE `gid` = '"+gid+"'";
mysql.query(sql, function (err, result) {
if (err) throw err;
return true;
});
},
addGuild: function(gid, gname, gowner){
var sql = "INSERT INTO GUILDS(`gid`, `gname`, `gOwner`) VALUES ('"+gid+"', '"+gname+"', '"+gowner+"')";
mysql.query(sql, function (err, result) {
if (err) throw err;
return true;
});
},
checkVip: function(type, id){
if(type == 'guild')
var sql = 'SELECT vip FROM GUILDS WHERE `gid` = ?';
else if(type == 'user')
var sql = 'SELECT vip FROM USERS WHERE `uid` = ?';
mysql.query(sql, [id], function(err, result){
if (err) throw err;
var tempdata = JSON.parse(result);
if(tempdata.vip == 'false')
return false;
else if(tempdata.vip == 'true')
return true;
});
},
addVip: function(type, id){
if(type == 'guild')
var sql = "UPDATE GUILDS SET vip = 'true' WHERE `gid` = '"+id+"'";
else if(type == 'user')
var sql = "UPDATE USERS SET vip = 'true' WHERE `uid` = '"+id+"'";
mysql.query(sql, function(err, result){
if (err) throw err;
return true;
});
},
removeVip: function(type, id){
if(type == 'guild')
var sql = "UPDATE GUILDS SET vip = 'false' WHERE `gid` = '"+id+"'";
else if(type == 'user')
var sql = "UPDATE USERS SET vip = 'false' WHERE `uid` = '"+id+"'";
mysql.query(sql, function(err, result){
if (err) throw err;
return true;
});
},
removeGuild: function(gid){
var sql = "DELETE FROM GUILDS WHERE `gid` = '"+gid+"'";
mysql.query(sql, function(err, result){
if (err) throw err;
return true;
});
}
};
and here is the discord bot command i use to trigger this functions:
var db = require('../../etc/database.js');
module.exports = {
name: "addvip",
description: "change guild to vip",
execute(message) {
const msgID = message.author.id;
if (!admins.includes(msgID)) return;
if(db.checkGuild(message.guild.id) == true)
{
if(db.checkVip('guild', message.guild.id) == true)
{
console.log('already vip!');
}
else if(db.checkVip('guild', message.guild.id) == false)
{
if(db.addVip('guild', message.guild.id) == true)
{
console.log('Guild is now vip!');
}else{
console.log('error in addvip');
}
}else{
console.log('error in checkVip');
}
}
else if(!db.checkGuild(message.guild.id) == true)
{
if(db.addGuild(message.guild.id, message.guild.name, message.guild.owner) == true)
{
if(db.addVip('guild', message.guild.id) == true)
{
console.log('added to vip!');
}else console.log('error in adding [check]');
}else console.log(db.addGuild(message.guild.id, message.guild.name, message.guild.owner));
}else console.log('wtf!');
}
};
so any idea how to fix this, please? I'm seriously working on this code like 1 month after solving SQL errors and ...
and BTW, it successfully connects to MySQL server!
It seems to be due to the fact that your SQL code uses callbacks, so no data is immediately returned and therefore, the return value is undefined. To fix this, you need to make the SQL functions return a Promise and change the return statement to resolve(), like this:
checkGuild: function(gid){
return new Promise(resolve => {
var sql = "SELECT * FROM GUILDS WHERE `gid` = '"+gid+"'";
mysql.query(sql, function (err, result) {
if (err) throw err;
resolve(true);
});
});
},
Then, you need to use await wherever the function is called in order to wait for the Promise to complete. Since, you are calling the functions in the addvip command file, you need to make the execute function asynchronous, so that you can use await:
module.exports = {
name: "addvip",
description: "change guild to vip",
async execute(message) {
const msgID = message.author.id;
if (!admins.includes(msgID)) return;
if(await db.checkGuild(message.guild.id) == true)

check if username and email already exists with expressjs validator and mysql

I want to check if email already exist in mysql database using express-validator package to do this. The example about checking email is not for mysql database.
The code is submitting form values successfully but the checks are being skipped. This is a middleware but the middleware is not been implemented before inserting into the database.
The solution I currently implemented is from stackoverflow. But still not working for me
router.post("/register",[
body('username').not().isEmpty().isLength({ min: 4 }).trim().escape(),
//check if email is aleady existing in the database
body('email').not().isEmpty().isEmail().normalizeEmail().custom(async (email, {req})=>{
const getEmails = "SELECT * FROM users WHERE email=" + req.body.email;
return await con.query(getEmails, [email], (error, rows, fields)=>{
if(error){
console.log("the email is not ok",error)
}else{
if (rows.length != 0) {
res.redirect('/guests/register');
return Promise.reject("user already exists.");
}else{
return true;
}
}
})
}),//end check if email already exit
body('phone').not().isEmpty().isLength({ min: 6 }),
body('password').not().isEmpty().isLength({ min: 6 }),
//check if password match
body('passwordConfirmation').not().isEmpty().isLength({ min: 6 }).custom((value, { req }) => {
if (value !== req.body.password) {
throw new Error('Password confirmation does not match password');
}
return true;
}),
//check if password match
], async function(req, res, next) {
try{
var usernames = req.body.username;
var emails = req.body.email;
var phones = req.body.phone;
const hashedPassword = await bcrypt.hash(req.body.password, 10);
let sql = "INSERT INTO `users` (username, email, phone, password) VALUES ('" + usernames + "', '" + emails + "', '" + phones + "', '" + hashedPassword + "')";
con.query(sql, function (err, result) {
if (err) throw err;
console.log("1 record inserted, ID: " + result.insertId);
res.redirect('/guests/login');
})
}catch{
//console.log("something is wrong", error)
res.redirect('/guests/register');
}
});
This code works for me:
const express = require('express');
const router = express.Router();
const { check,validationResult } = require('express-validator');
const bcrypt = require('bcrypt');
const bcryptRounds = 10;
router.post('/register', [
check('username')
.exists()
.trim()
.matches(/^[a-zA-Z\ö\ç\ş\ı\ğ\ü\Ö\Ç\Ş\İ\Ğ\Ü ]{3,16}$/)
.withMessage('Invalid username!'),
check('mentionName')
.exists()
.trim()
.matches(/^(?=.*[a-z])[a-z0-9_]{3,15}$/)
.custom(async mentionName => {
const value = await isMentionNameInUse(mentionName);
if (value) {
throw new Error('Mention name is already exists!!!');
}
})
.withMessage('Invalid mention name!!!'),
check('email')
.exists()
.isLength({ min: 6, max: 100 })
.isEmail()
.normalizeEmail()
.trim()
.custom(async email => {
const value = await isEmailInUse(email);
if (value) {
throw new Error('Email is already exists!!!');
}
})
.withMessage('Invalid email address!!!'),
check('password')
.exists()
.isLength({ min: 6, max: 16 })
.escape()
.trim()
.withMessage('Invalid password!!!'),
check('rePassword').exists().custom((value, { req }) => {
if (value !== req.body.password) {
throw new Error('The passwords is not same!!!');
}
return true;
})
],
function (req, res) {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(422).json({ errors: errors.array() });
} else {
console.log("----->START USER REGISTRATION");
const username = req.body.username;
const mentionName = '#'+req.body.mentionName;
const email = req.body.email;
const pass = req.body.password;
bcrypt.hash(pass, bcryptRounds, function(err, hash) {
console.log("HASH PASS : "+hash);
//INSERT USER
});
}
});
function isMentionNameInUse(mentionName){
var conn = require('../../modules/mysql_db');
return new Promise((resolve, reject) => {
conn.query('SELECT COUNT(*) AS total FROM users_table WHERE m_name = ?', [mentionName], function (error, results, fields) {
if(!error){
console.log("MENTION COUNT : "+results[0].total);
return resolve(results[0].total > 0);
} else {
return reject(new Error('Database error!!'));
}
}
);
});
}
function isEmailInUse(email){
var conn = require('../../modules/mysql_db');
return new Promise((resolve, reject) => {
conn.query('SELECT COUNT(*) AS total FROM users_table WHERE email = ?', [email], function (error, results, fields) {
if(!error){
console.log("EMAIL COUNT : "+results[0].total);
return resolve(results[0].total > 0);
} else {
return reject(new Error('Database error!!'));
}
}
);
});
}

How to fix the node.js code to check for login

I am new to node js and dont know why is this returning the false value always. I have form made in html that sends post request then the app.js calls login.js function and checks the database
I tried to manually input with 2 var and it works but when using the form it doesnt.
app.post('/login', urlencodedParser, function (req, res) {
var check = require('./js/login.js');
var username = req.body.username;
var password = req.body.password;
if(check([username,password]) == true){
console.log('fine');
res.render('index');
}
else{
console.log('get lost');
res.render('login');
}
});
This is the app.js code thet calls the login.js but the page doesnt render also even if the returned value is incorrect.
var check = function(arr){
var con = require(__dirname + '/database.js');
var login_check = false;
con.connect(function(err) {
if (err) throw err;
con.query("SELECT * FROM users WHERE (name = ?) AND (password = ?)", [arr[0], arr[1]], function (err, result, fields) {
if (err) throw err;
if(result)
{
login_check = true;
}
});
});
return login_check;
};
module.exports = check;
Because of your con.query function is asynchronous, so the return of function will always be false by default (it returns before executing check). Another way, you can try to use callback function as my suggestion code below:
app.post("/login", urlencodedParser, function(req, res) {
var check = require("./js/login.js");
var username = req.body.username;
var password = req.body.password;
var checkCallback = function (isLogin) {
if (isLogin) {
console.log("fine");
res.render("index");
} else {
console.log("get lost");
res.render("login");
}
}
check([username, password], checkCallback);
});
// -----------------------------
// login.js
var check = function(arr, callback) {
var con = require(__dirname + "/database.js");
var login_check = false;
con.connect(function(err) {
if (err) throw err;
con.query(
"SELECT * FROM users WHERE (name = ?) AND (password = ?)",
[arr[0], arr[1]],
function(err, result, fields) {
if (err) throw err;
if (result) {
login_check = true;
callback(true); // Call the callback function here after checking is done
}
}
);
});
return login_check;
};
module.exports = check;

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;
}
});
}
});
};

Adding bulk data to mysql database

I have a console program where the user scans in serial numbers, and those serial numbers get added to a database.
const mysql = require('mysql2');
const read = require('readline-sync');
const conn = new mysql.createConnection(config);
conn.connect(
function(err){
if(err){
throw err;
}
else{
console.log("Connection Established");
while(1){
var sn = read.question('Scan in serial number: ');
conn.query('INSERT INTO test (serial) VALUES (?);',
[sn], function(err, results, fields){
if (err){
throw err;
}
else{
console.log("Added stuff");
}
});
}
}
}
);
When the code runs it successfully connects to the database but queries the database. It continually prompts for user input.
Alternatively, I tried storing serial numbers in an array and then loops through it adding each element, like this.
const mysql = require('mysql2');
const read = require('readline-sync');
var array = [];
var sn = " ";
while (1) {
sn = read.question('Scan in serial number, or enter "done" if finished scanning');
if (sn == "done") {
break;
}
array.push(sn);
}
conn.connect(
function (err) {
if (err) {
throw err;
}
else {
console.log("Connection Established");
array.forEach(function (sn) {
conn.query('INSERT INTO test (serial) VALUES (?);',
[sn], function (err, results, fields) {
if (err) {
throw err;
}
else {
console.log("Added stuff");
}
});
});
}
}
);
In this case, it works inconsistently. Sometimes it works fine, and other times it fails to connect and throws a timeout error. Is there a better way to accomplish this and/or am I doing something wrong?
var promises = []
function dbOp(value) {
return new Promise(function(resolve, reject) {
conn.query('INSERT INTO test (serial) VALUES (?);',
[value], function (err, results, fields) {
if (err) {
return reject(err)
}
else {
console.log("Added stuff");
resolve(results)
}
}
}
conn.connect(function(err){
if(err){
throw err;
}
else{
for (i = 0; i < array.length; ++i) {
promises.push(dbOp(array[i]));
}
}
});
Promise.all(promises)
.then((results) => {
console.log("done", results);
})
.catch((e) => {
console.log(e)
});
This might be caused by short idle timeout setting in your mysql server. client.connect() is pretty much a no-op in mysql2, it connects immediately when you call mysql.createConnection(). You can change order to establish connection only after all data is collected:
const mysql = require('mysql2');
const read = require('readline-sync');
var array = [];
var sn = ' ';
while (1) {
sn = read.question('Scan in serial number, or enter "done" if finished scanning');
if (sn == 'done') {
const conn = mysql.createConnection(config);
array.forEach(function(sn) {
conn.query('INSERT INTO test (serial) VALUES (?);', [sn], function(err, results, fields) {
if (err) {
throw err;
} else {
console.log('Added stuff');
}
});
});
}
array.push(sn);
}