Problems Modifying a Github Project to Include mysql - javascript

I'm having issues converting this setup: https://github.com/WebDevSimplified/Nodejs-Passport-Login
to push and pull user data from a mysql database. I've got the registration to work just fine, but I appear to be having difficulty with the login portion. I converted this portion from lines 14-18 of server.js
initializePassport(
passport,
email => users.find(user => user.email === email),
id => users.find(user => user.id === id)
)
to look like this
initializePassport(
passport,
email => db.getConnection( async (err, connection) => {
if (err) throw (err)
const sqlSearch = "SELECT * FROM users WHERE email = ?"
const searchQuery = mysql.format(sqlSearch, [email])
await connection.query(searchQuery, async (err, result) => {
connection.release()
if (err) throw (err)
console.log(result[0].email)
return result[0].email
})
}),
id => db.getConnection( async (err, connection) => {
if (err) throw (err)
const sqlSearch = "SELECT * FROM users WHERE id = ?"
const searchQuery = mysql.format(sqlSearch, [id])
await connection.query(searchQuery, async (err, result) => {
connection.release()
if (err) throw (err)
console.log(result[0].id)
return result[0].id
})
})
)
Basically, the initial setup found the relevant data from an array called "users", so I figured I could do the same with the mysql database. I have not changed the passport-config.js file, as I figured it didn't need it, but now I'm not so sure.
During login, the terminal logs the correct input email on login as per my modifications, but it never gets to the id portion of this. Also, it throws the programmed message "No user with that email" as found in line 8 of passport-config.js.
The rest of the code I have in my file is basically the same except for the database connection which looks like this (all the stuff references a .env file that has all the correct params):
const DB_HOST = process.env.DB_HOST
const DB_USER = process.env.DB_USER
const DB_PASSWORD = process.env.DB_PASSWORD
const DB_DATABASE = process.env.DB_DATABASE
const DB_PORT = process.env.DB_PORT
const mysql = require("mysql")
const db = mysql.createPool({
connectionLimit: 100,
host: DB_HOST,
user: DB_USER,
password: DB_PASSWORD,
database: DB_DATABASE,
port: DB_PORT
})
and the registration post method which looks like this:
app.post('/register', checkNotAuthenticated, async (req, res) => {
try {
const id = Date.now().toString()
const fName = req.body.firstName
const lName = req.body.lastName
const email = req.body.email
const password = await bcrypt.hash(req.body.password, 10)
db.getConnection( async (err, connection) => {
if (err) throw (err)
const sqlSearch = "SELECT * FROM users WHERE fName = ?"
const searchQuery = mysql.format(sqlSearch, [fName])
const sqlInsert = "INSERT INTO users VALUES (?,?,?,?,?)"
const insertQuery = mysql.format(sqlInsert,[id, fName, lName, email, password])
await connection.query (searchQuery, async (err, result) => {
if (err) throw (err)
console.log("------> Search Results")
console.log(result.length)
if (result.length != 0) {
connection.release()
console.log("------> User already exists")
}
else {
await connection.query (insertQuery, (err, result)=> {
connection.release()
if (err) throw (err)
console.log ("--------> Created new User")
console.log(result.insertId)
})
}
}) //end of connection.query()
}) //end of db.getConnection()
res.redirect('/login')
} catch {
res.redirect('/register')
}
})
As I said, I have no issues with the registration. The connection is successful, and subsequent inspection of the users table in the mysql terminal (I'm using Mac), the data is being stored correctly. How do I proceed here?

Looks like an issue with the return in initializePassport function.
When you return result[0].email or return result[0].id it returns out of the inner callback function of connection.query() not the outer function.
This may fix it:
initializePassport(
passport,
(email) =>
db.getConnection(async (err, connection) => {
if (err) throw err;
const sqlSearch = "SELECT * FROM users WHERE email = ?";
const searchQuery = mysql.format(sqlSearch, [email]);
// return out of db.getConnection()
return connection.query(searchQuery, async (err, result) => {
connection.release();
if (err) throw err;
console.log(result[0].email);
// return out of connection.query()
return result[0].email;
});
}),
(id) =>
db.getConnection(async (err, connection) => {
if (err) throw err;
const sqlSearch = "SELECT * FROM users WHERE id = ?";
const searchQuery = mysql.format(sqlSearch, [id]);
// return out of db.getConnection()
return connection.query(searchQuery, async (err, result) => {
connection.release();
if (err) throw err;
console.log(result[0].id);
// return out of connection.query()
return result[0].id;
});
})
);

Related

mutiple get methods on the same route conflict in express and sequelize

I'm built simple product crud, so I have a route to search product by id and other to search product by name, when I make a requisition to http://localhost:4000/products?name=pen the routes are in conflict and don't return the product by name.
router.get('/products/:id', ProductController.getProductById);
router.get('/products/:name', ProductController.getProductByName);
and yours respect functions
const getProductById = async (req, res) =>{
try{
const { id } = req.params;
const product = await Product.findByPk(id);
if(product){
return res.status(200).json({ product });
}
return res.status(404).send('Product With ID does exist');
}catch (err){
return res.status(500).send({ error : 'Error on select by id'})
}
}
const getProductByName = async (req, res) =>{
try{
const name = req.query.name;
const product = await Product.findAll({
where: { name: name}
});
if(product){
return res.status(200).json({ product });
}
return res.status(404).send('Product With Name does exist');
}catch (err){
return res.status(500).send({ error : 'Error on select by id'})
}
}
If you use query parameters you should not indicate them in route path:
router.get('/products', ProductController.getProductByName);

Hashing a password with bcrypt

I need to hash the password before insert in the DB I have the function of bcrypt but I don't know how to get it into a const and use it for make the insert into mysql.
I'm using bcrypt for it, so what's the method I should follow to get the password hashed?
async postCompletedetails(req, res) {
const company = req.params.company;
const name = req.params.name;
const password = req.params.password;
bcrypt.hash(password, saltRounds, (err, hash) => {
});
if (
company !== undefined &&
name !== undefined &&
password !== undefined
) {
const { token } = req.headers;
const decoded = jwt.verify(token, process.env.JWT_ACCOUNT_ACTIVATION);
const id = decoded.id;
const update = await pool.query(
`UPDATE user SET Name_user= '${name}', password= '${password}' WHERE ID_user = ${id}`
);
const incompany = await pool.query(
`INSERT INTO company (Name_company) VALUES ('${company}') `
);
const inrelcompany = await pool.query(
`INSERT INTO rel_company_user (ID_company, ID_user) VALUES (LAST_INSERT_ID(), ${id})`
);
return res.json({
code: 200,
message: "todo bien... todo correcto y yo que me alegro",
password,
});
} else {
return res.json({
code: 400,
message: "Bro hiciste algo mal",
});
}
}
async postCompletedetails(req, res) {
const company = req.params.company;
const name = req.params.name;
const password = req.params.password;
const saltRounds = 10;
if (
company !== undefined &&
name !== undefined &&
password !== undefined
) {
const hashPass = bcrypt.hash(password, saltRounds, (err, hash) => {
if (err)
{
return err;
}
return hash;
});
hashPass // this will be what you insert into the database.
}
Ok, I have it but the problem is that I can't get the hashed password, hassPass have de value undefined, what I should change?
const hashPass = await bcrypt.genSalt(saltRounds, function (err, salt) {
if (err) {
throw err
} else {
bcrypt.hash(password, salt, function(err, hash) {
if (err) {
throw err
} else {
console.log(hash)
}
})
}
})
The password is being hashed, I now it for the console.log

How to correctly execute this promise based SQL Query?

I'm using MySQL2 to connect my Node.js app with a MySQL Database.
Unfortunately trying to perform some promise based prepared statements I just can't get a proper function setup that either returns successfully after entering the record or to throw an error whenever something goes wrong.
Any ideas on how to fix the code below?
// Connection Settings
const connection = mysql.createConnection({
host: process.env.DB_HOST,
user: process.env.DB_USER,
password: process.env.DB_PASSWORD,
database: process.env.DB_DATABASE,
port: process.env.DB_PORT
})
// Promise based SQL Prepared Statement
db.pps = ({ query, variables, error }) => {
return new Promise((resolve, reject) => {
connection.execute(query, variables, (err, results) => {
if (err) {
console.log(`Error: ${error} \n ${err.sqlMessage}`)
return reject(err)
}
return resolve(results)
})
})
}
// Sign Up
auth.signup = (req, res) => {
const query = `
INSERT INTO User (Id, Email, Password)
VALUES (UUID_TO_BIN(UUID()), ?, ?)
`
const variables = [req.query.email, req.query.password]
db.promise({ query, variables }, (err, result) => {
if (err) {
res.status(400)
}
res.status(200)
})
}
you can use the prepared statement query function like below.
If you are not using this inside a function
auth.signup = (req, res) => {
const query = `
INSERT INTO User (Id, Email, Password)
VALUES (UUID_TO_BIN(UUID()), ?, ?)
`
const variables = [req.query.email, req.query.password]
db.pps({ query, variables })
.then(result => {
res.status(200)
})
.catch( error => {
res.status(400)
});
}
Or use async await
auth.signup = async (req, res) => {
const query = `
INSERT INTO User (Id, Email, Password)
VALUES (UUID_TO_BIN(UUID()), ?, ?)
`
const variables = [req.query.email, req.query.password]
try {
await db.pps({ query, variables });
res.status(200)
} catch (err) {
res.status(400)
}
}
You have to do 2 changes:
1.Remove error param
db.pps = ({ query, variables}) => {
2. Change the SignUp code as below
auth.signup = (req, res) => {
const query = `
INSERT INTO User (Id, Email, Password)
VALUES (UUID_TO_BIN(UUID()), ?, ?)
`
const variables = [req.query.email, req.query.password]
db.pps({ query, variables }).then(response => {
// Do stuff with users
})
.catch(err => {
// handle errors
})
function pps( query, variables){
return new Promise((resolve, reject) => {
connection.execute(query, variables, (err, results) => {
if (err) {
console.log(`Error: ${error} \n ${err.sqlMessage}`)
reject(err)
}
resolve(results)
})
})
}
auth.signup = (req, res) => {
const query = `
INSERT INTO User (Id, Email, Password)
VALUES (UUID_TO_BIN(UUID()), ?, ?)
`
const variables = [req.query.email, req.query.password]
pps(query, variables)
.then(result => {
res.status(200)
})
.catch( error => {
res.status(400)
});
}

Node.js: Map function doesn't work on query from PostgreSQL

I'm creating my first app using Node.js and PostgreSQL.
This app connect's to db and return record to browser in JSON format, its work perfectly till i try to use map function to formating properties.
When i use map it return an error:
TypeError: rows.map is not a function
This is my code.
app.get('/car/:id', (req, res) => {
const car_id = req.params.id;
const queryString = `SELECT * FROM cars WHERE car_id= ${car_id}`;
client.query(queryString, (err, rows, fields) => {
if (err) {
console.log(err.stack);
res.sendStatus(500);
res.end();
} else {
const car = rows.map((row) => {
return {"Car_ID": row.car_id}
});
res.json(car);
console.log(rows.rows);
}
});
It should be result.rows not just rows
According to this - https://node-postgres.com/api/result
app.get('/car/:id', (req, res) => {
const car_id = req.params.id;
const queryString = `SELECT * FROM cars WHERE car_id= ${car_id}`;
client.query(queryString, (err, result, fields) => {
if (err) {
console.log(err.stack);
res.sendStatus(500);
res.end();
} else {
const car = result.rows.map((row) => {
return {"Car_ID": row.car_id}
});
res.json(car);
console.log(result.rows);
}
});

sqlite3 callbacks (node.js)

I'm trying to compare an entered email on my website, to ones in the database to see whether it already exists. If it does, then the function returns false and an error is displayed.
var db = new sqlite3.Database('users_db.db');
db.get(
"SELECT * FROM users WHERE useremail = ?",
[email],
function (err, rows) {
if (rows == undefined ){
global.returnvalue2 = false;
}
}
);
What I want is for the function to be run immediately after the selection, so that the returned value is false, and the user record is not created.
At the moment I realise that the callback is being called after everything, so its just making the selection and carrying on throughout the rest of the program until the end.
How can I check if there are any existing records with the same email?
Make use of the async features in javascript, so your code would look something like this;
var db = new sqlite3.Database('users_db.db');
function checkemail(email, cb) {
db.get(
"SELECT * FROM users WHERE useremail = ?",
[email],
function (err, rows) {
if (err || rows == undefined ){
cb("bad email", null)
} else {
cb(null,rows)
}
});
}
function checkpassword(pw,cb) {....}
function checkclass(cls,cb) {....}
and then write you code like this;
checkemail(myemail, function(err,rows) {
if (err) return alert(err);
checkpassword(pw, function(err, msg) {
if (err) return alert(err);
checkclass(cls, function(err, msg) {
if (err) return alert(err);
alert("Congratulation you passed all the checks");
});
});
});
Here's a little one I made.
const sqlite3 = require('sqlite3').verbose();
let db = new sqlite3.Database('iHacks.db');
function get_user_credentials (email, password)
{ return new Promise((rs, rj) => {
function callback (err, User)
{
if (err) rj(err);
rs(User);
}
db.get('select * from users where email=? and password=?', [email, password], callback);
}); }
function login (email, password)
{ return new Promise ((rs, rj) => {
// Hashing the password.
password = sha256(password + 'EzSalt');
// Creating an Error
const err = new Error('Email or password did not match!');
// Callback functions
function check (User)
{
rs(User);
}
function fail (err)
{
rj(err);
}
// Getting the user credentials
get_user_details(email, password).then(check).catch(fail);
}); }
login()
.then(/* Continue code */)
.catch(err => {throw new Error(err); })
;

Categories