custom mysql function in nodejs returns undefined - mysql

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)

Related

MYSQL length of results undefined

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

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;

Node.js synchronously with mysql query

I am trying to implement a synchronous query in mysql with node.js, I tried several ways and did not succeed
I am new to node.js
I use express.js
connection.js
var mysql = require('mysql');
var connMySql = function() {
return mysql.createConnection({
host : 'localhost',
user : 'root',
password : '******',
database : 'ress'
});
}
module.exports = function() {
return connMySql;
}
DAO.js
function UserDAO(connection){
this._connection = connection();
}
UserDAO.prototype.createUser = function (user, callback){
var sql = "insert into... ";
this._connection.query(sql, function(err, result){
//console.log(result)
//console.log()
if (err){
callback(err,false )
}
if (result){
var newI = result.insertId
var sqlOther = "insert into ..... ";
this._connection.query(sql, function(err, result){
if (err){
callback(err,false )
}else if (result.length > 0){
callback(false, result.insertId)
}
});
}
});
}
I try implements await, async and Promisse(.then) but no success.
What I need to make calls synchronously and return insert id?
thanks
From mysql repo I see that you're missing connection.connect()
connection.js
var mysql = require('mysql');
var connection = mysql.createConnection({
host : 'localhost',
user : 'root',
password : '******',
database : 'ress'
});
connection.connect(function(err) {
if (err) throw err;
});
module.exports = connection;
DAO _connection must be closed when it's done with it's job
UserDAO.prototype.createUser = function (user, callback){
var sql = "insert into... ";
this._connection.query(sql, function(err, result){
//console.log(result)
//console.log()
if (err){
callback(err,false )
this._connection.end();
}
if (result){
var newI = result.insertId
var sqlOther = "insert into ..... ";
this._connection.query(sql, function(err, result){
if (err){
callback(err,false )
} else if (result.length > 0){
callback(false, result.insertId)
}
this._connection.end();
});
}
});
}

Socket.io and Node.js with mysql not returning results as expeted

EDIT: I'm rephrasing my question: Socket.io not waiting for Callback and connection never accepted. Please see Edit 2/Attempt 1 below
This is to check authentication token against database. Can someone spot what is wrong here?
var checkauth = function(auth) {
var rs = 0;
var sql = 'SELECT * FROM clients WHERE pword=\''+auth+'\'';
// Copied from debug session and got results: SELECT * FROM clients WHERE pword='d98e623c7a74a178703d17e1fd536b1488724acd41e71f178331c768c385bda2c82d2bcb60cbb4650be375ad4734c63fb694bd164c138f9abe0c51f37f9a7e33'
var query = connection.query(sql);
query
.on('error', function(err) {
console.log( err );
})
.on('result', function( row ) {
rs = Number(row.client_id); // This never fires!!?!?!
})
.on('end',function(){
});
if (rs == 0) {
sql = 'SELECT * FROM users WHERE pword=\''+auth+'\'';
query = connection.query(sql);
query
.on('error', function(err) {
console.log( err );
})
.on('result', function( row ) {
rs = Number(row.client_id); // This never fires!!?!?!
})
.on('end',function(){
});
}
return rs;
}
Edit 1: I use the follwoing loop to authenticate socket.io connections which runs the function, ok so I understand that I have to wait for the db to finish, where would I put the callback?
io.use(function(socket, next){
console.log("Query: ", socket.handshake.query);
// return the result of next() to accept the connection.
socket.clientid = 0;
socket.clientid = checkauth(socket.handshake.query.auth);
console.log("CID:"+socket.clientid);
if (socket.clientid != 0) {
return next();
}
// call next() with an Error if you need to reject the connection.
next(new Error('Authentication error'));
});
EDIT 2/ Attempt 1 according to Johannes' suggest:
var checkauth = function(auth, cb) {
var rs = 0;
var sql = 'SELECT * FROM clients WHERE pword=?';
var query = connection.query(sql, [auth]);
query
.on('error', function(err) {
console.log(err);
})
.on('result', function(row) {
rs = Number(row.client_id);
})
.on('end', function() {
if (rs == 0) {
sql = 'SELECT * FROM users WHERE pword=?';
query = connection.query(sql, [auth]);
query
.on('error', function(err) {
console.log(err);
})
.on('result', function(row) {
rs = Number(row.client_id);
})
.on('end', function() {
cb(rs);
});
}
});
}
io.use(function(socket, next){
console.log("Query: ", socket.handshake.query);
// return the result of next() to accept the connection.
socket.clientid = 0;
var auth = socket.handshake.query.auth;
checkauth(auth, function(clientid){
socket.clientid = clientid;
if (clientid != 0) {
return next();
}
console.log('CLIENID', clientid);
next(new Error('Authentication error'));
});
// if (socket.clientid != 0) {
// return next();
// }
// // call next() with an Error if you need to reject the connection.
// next(new Error('Authentication error'));
});
This whole process is async. You have to do 2 things:
Move everything into the event callback and
add a callback or promise to your checkAuth function. You also should escape your inserted data.
EDITED SOLUTION
var checkauth = function(auth, cb) {
var rs = 0;
var sql = 'SELECT * FROM clients WHERE pword=?';
var query = connection.query(sql, [auth], (err, client) => {
if(err || !client || client.length < 1) return cb(err || new Error('unkown client'));
sql = 'SELECT * FROM users WHERE pword=?';
query = connection.query(sql, [auth], (err, user) => {
if(err || !user || user.length < 1) return cb(err || new Error('unkown user'));
cb(null, client[0].client_id);
});
});
}
Note: why are you doing 2 queries in the first place and storing the password for each client of the user?
ORIGINAL ANSWER:
var checkauth = function(auth, cb) {
var rs = 0;
var sql = 'SELECT * FROM clients WHERE pword=?';
var query = connection.query(sql, [auth]);
query
.on('error', function(err) {
console.log(err);
})
.on('result', function(row) {
rs = Number(row.client_id); // This never fires!!?!?!
})
.on('end', function() {
if (rs == 0) {
sql = 'SELECT * FROM users WHERE pword=?';
query = connection.query(sql, [auth]);
query
.on('error', function(err) {
console.log(err);
})
.on('result', function(row) {
rs = Number(row.client_id); // This never fires!!?!?!
})
.on('end', function() {
cb(rs);
});
}
});
}
checkauth(123, function(clientId){
console.log('CLIENID', clientId);
});