Validate existing email in mysql in a node.js server - mysql

I am having the following problem with node and mysql:
I have a function registerUser that takes the req.body with the user credentials and store them into a mysql db.
First of all I check that the email provided does not already exist. I have done this validation working with postgres in the following manner: if(user.rows.lenght!==0) return res.send("user already exist")
Then I pass to the next line of code that insrts the credentials into the db.
My problem is that using mysql, user.rows is undefined. I am having trouble extracting the data from the response which would allowme to perform some sort of validation.
My code is like this:
registerUser:async(req,res)=>{
const resolver=Resolver(res)
try {
//get data from req.body
const {userName, userEmail, userPassword}=req.body
//Check if user alreday exist on db by email
const user=db.query("SELECT * FROM users WHERE user_email=?",
[userEmail],(err,result)=>{
if(err) console.log(err)
else if(result.length!==0) return res.status(401).send('user already exist')
})
The callback function of the query does not stop the execution of the registeruser function. Also, the result comes with the user credentaials which is what I need, but I dont know how to extract it from the callback in order to use it in the scope of registerUser

Related

AWS Lambda function is returning square bracket "[ ]" result

I created a Lambda function with an API query string parameter. My Lambda function is created in NodeJS with MySQL query as shown below resulted to square bracket "[]"when invoked in the URL and Postman but the status is "Succeeded".
URL Return/Result:
[]
Here's my Lambda function code:
var mysql = require('mysql');
var config = require('./config.json');
var pool = mysql.createPool({
host : config.dbhost,
user : config.dbuser,
password : config.dbpassword,
database : config.dbname
});
exports.handler = (event, context, callback) => {
context.callbackWaitsForEmptyEventLoop = false;
pool.getConnection(function(err, connection) {
// Use the connection
connection.query('SELECT DISTINCT meta FROM item WHERE meta LIKE "+event.selected-meta"', function (error, results, fields) {
// And done with the connection.
connection.release();
// Handle error after the release.
if (error) callback(error) ;
else callback(null, results);
});
});
};
I suspect the culprit in my code is the callback method but it seems to me it is correct and could not find any other syntax to correct it.
Does anybody here familiar with AWS Lambda, NodeJS and API Gateway who could help me figure out where I was wrong?
UPDATE 1:
The above code returns "Succeeded" status but an empty array. I tried the same query in Workbench — I get the right results.
SELECT DISTINCT name FROM item WHERE meta LIKE 'tango';
I can now confirmed that the below parameter is taken up as a variable rather than as parameter. So, I have to determine the right syntax for parameter in Lambda/NodeJS.
"+event.selected-meta"
FINAL UPDATE
At last I got the answer! The right syntax would be as follows. The question mark (?) is the placeholder followed by an array as the second argument where we place the parameter and it solves my problem!
SELECT name FROM item WHERE meta LIKE ?', event['selected-meta']
Hope others can learn from this!
At last I got the answer! The right syntax would be as follows. The question mark (?) is the placeholder followed by an array as the second argument where we place the parameter and it solves my problem!
SELECT name FROM item WHERE meta LIKE ?', event['selected-meta']
I am posting it here for others reference but I could not mark it as "ANSWERED". Somebody may want to check and mark it. Cheers!

Nodejs passport setup confusion

I have been trying to setup my Nodejs MySQL database configuration. I found this passport.js config for MySQL on Github. The config works properly but there is a part that I do not understand.
var insertQuery = "INSERT INTO users ( email, password ) values ('" + email +"','"+ password +"')";
console.log(insertQuery);
connection.query(insertQuery,function(err,rows){
newUserMysql.id = rows.insertId;
return done(null, newUserMysql);
});
I am confused about the insertID field. The table I am using does not have a field called insertID. It does however have a field named ID. I tried changing that line to
newUserMysql.id = rows.Id;
bu doing so gives me:
Error: Failed to serialize user into session
Leaving it as it is gives me no error
Looks like insertID has nothing to do with the ID field of my table but I do not understand what it means
That probably represents LAST_INSERT_ID() which is the ID of the last row inserted.
The response of an INSERT is not "rows" but a result object, so maybe better named it'd be:
connection.query("...", function(err, result) {
newUserMysql.id = result.insertId;
return done(null, newUserMysql);
});
It's important to note that using Promises dramatically simplifies your code, and async/await can take that even further. This could be as simple as:
let result = await connection.query("...");
newUserMysql.id = result.insertId;
return newUserMysql;
Where that's inside an async function with a Promise-driven database library like Sequelize. You're not handling the potential errors in your first case. In the second you'll get exceptions which will wake you up when there's problems.

can i connect to mysql database from sails without defining models?

I'm using sails.js and sails-MySQL and I want to connect to a MySQL database. I have tables, functions, and procedures in my workbench. now I want to know that is it necessary to create model files and define my schema again?
Yes, you can connect to your DB without defining models. However bare in mind that you will have to write raw queries every time. So first you need to define your DB connection in your datastores.js file. Then you can do the following in some of your controllers when you want to get something from your DB (say you have a table users and you want to get all of them):
var myDBStore = sails.getDatastore(); //gets the default datastore.
var query = "SELECT * FROM users;";
myDBStore.sendNativeQuery(query).exec(function (err, nativeResult) {
if (err) {
return res.send(err);
}
return res.send(nativeResult.rows);
});
or using the modern way in an async function:
var myDBStore = sails.getDatastore(); //gets the default datastore.
var query = "SELECT * FROM users;";
var nativeResult;
try {
nativeResult = await myDBStore.sendNativeQuery(query);
} catch (err) {
return res.send(err);
}
return res.send(nativeResult.rows);
More info here: https://sailsjs.com/documentation/reference/waterline-orm/datastores in section "Using datastores without a model"

How to use Auth0's custom database to add a user to a MySQL database?

I am using Auth0 for a login service but I have a need to add a user to a database in MySQL every time an account is registered through Auth0.
They give this following script template but I am a newbie and need help debugging and understanding it. My specific questions are detailed as comments:
function create(user, callback) {
var connection = mysql({
host: 'localhost', //what should this be?
user: 'KNOWN/Understood',
password: 'KNOWN/Understood',
database: 'KNOWN/Understood'
});
connection.connect();
var query = "INSERT INTO users SET ?"; //what does this do?
bcrypt.hash(user.password, 10, function (err, hash) { //what does this do?
if (err) { return callback(err); }
var insert = {
password: hash,
email: user.email
};
connection.query(query, insert, function (err, results) {
if (err) return callback(err);
if (results.length === 0) return callback();
callback(null);
});
});
}
Is there anything else I need to change for this script or understand or call in for it to work?
I often get the error missing username for Database connection with requires_username enabled and I'm unsure what this means.
I'm assuming you already went through this tutorial on custom databases so let's address your specific questions.
host: 'localhost' // What should this be?
This and the other properties of this object define the way to connect to your custom MySQL database. The database needs to be reached from within Auth0 servers so this needs to be a host name accessible from the Internet.
"INSERT INTO users SET ?"; // What does this do?
This defines an SQL insert command that uses ? as a placeholder for later substitution.
If you see where this query is later used, you will noticed it's invoked with an additional insert object parameter that will cause the above query to be expanded into something like:
INSERT INTO users SET email = 'user#example.com', password = 'asdf34ASws'
bcrypt.hash(user.password, 10, function (err, hash) // What does this do?
This hashes the user provided password so that it's not stored in plain text in the database.
If you chose to require a username in addition to email you need to address this in your custom scripts as I believe the default templates assume that only email will be used.
This means that when creating the user in your database you also need to store the username and in the script to verify a user you also need to return the username.

Connecting to RDS database from node.js

I am trying to learn node.js so that I can actually get started on working on my personal project. I have been trying to follow the examples in the book "Learning node.js" (by Marc Wandschneider). I, at this point, decided to forgo practicing his example, and go straight into using his code as framework for my practice code.
In my practice code, all I am trying to do is connect to my RDS database (no, I am not using Elastic Beanstalk, btw), and output contents of one of the tables. Seems simple enough, but when I whip up the code for it (based on the book), it seems to attempt connection, but get hung up in the process. This is my code:
var pool = require('generic-pool');
var async = require('async');
var mysql = require('mysql');
var host = "<database-name>.cu8hvhstcity.us-west-2.rds.amazonaws.com",
database = "<database-name>",
user = "<username>",
password = "<someLongPassword>";
var dbClient;
async.waterfall([
// 1. establish connection to database
function (callback) {
console.log("Connecting to database " + database + "...");
dbClient = mysql.createConnection({
host: host,
database: database,
user: user,
password: password,
port: 3306
});
dbClient.connect();
},
// 2. select all from a table (let's go for locations)
function (cb)
{
var query = "SELECT * FROM locations"
console.log("running query \"" + query + "\"...");
dbClient.query(query, cb);
},
function (rows, fields, callback)
{
console.log(fields);
for (var i = 0; i < rows.length; i++)
{
console.log(JSON.stringify(rows, null, '\t'));
}
}
], function (err, results) {
if (err)
{
console.log("An error occurred...");
console.log(err);
}
else
{
console.log("Everything successfully completed!");
}
dbClient.end();
})
This is better than first attempt, when I put a database member to the argument passed to mysql.createConnection(), and it complained that database was unknown. In neither case did either "An error occurred..." nor "Everything successfully completed!" output to the window.
Is there any async stuff going on that is resulting in some kind of non-terminating infinite loop or something? How do I fix this?
The book has an associated GitHub page
NOTE:
Neither my example nor the cited GitHub code make use of that pool variable, so it can simply be commented out. All you need to do to run this yourself is to say npm install async,npm install mysql (as well as creating a dummy RDS database to point to, that contains locations table) before copying, pasting, and running this code.
EDIT:
I fixed the issue with database. I realized that the name of the database used '_', not '-'. Same issue (code hangs) still persists...
I did the following:
In the second function in the array, I needed two parameters, not one.
I fixed thus:function(results, cb)
The third function simply needed to callback(null)