Node.js help creating a function - function

I'm not sure what did i miss in my code.. I'm new on this
I have this code
helpers.encryptPassword = async (password) => {
const salt = await bcrypt.genSalt(10);
const hash = await bcrypt.hash(password, salt);
return hash;
};
module.export = helpers;
But when i execute this code
**newUser.password = await helpers.encryptPassword(password);**
it gives me an error, say "encryptPassword is not a function", but i don't know what am doing wrong
I understand that encryptPassword seems to store the result of a function with no name, but it is not a function. I need to change it, making possible to recive a parameter (the password, so bcrypt could hash it)
If You need all the code, there is it
const passport = require('passport');
const LocalStrategy = require('passport-local').Strategy;
const pool = require ('../../database');
const helpers = require('../lib/helpers');
passport.use ('local.signup', new LocalStrategy({
usernameField: 'username',
passwordField: 'password',
passReqToCallback: true
}, async (req, username, password, done) => {
const { fullname } = req.body;
const newUser = {
username,
password,
fullname
};
**newUser.password = await helpers.encryptPassword(password);**
const result = await pool.query('INSERT INTO users SET ?', [newUser]);
console.log(result);
}));

Related

passport.js || Error at Strategy.passport.use.LocalStrategy [as _verify]

I've trying to create a login using passport but I'm having some issues.
First, take a look at my code:
`
const passport = require('passport');
const LocalStrategy = require('passport-local').Strategy;
const pool = require('../database');
const helpers = require('../lib/helpers');
passport.use('local.signup', new LocalStrategy({
usernameField: 'username',
passwordField: 'password',
passReqToCallback: true
}, async (req, username, password, done) => {
const { fullname } = req.body;
const newUser = {
username: username,
password: password,
fullname
};
newUser.password = await helpers.encryptPassword(password);
const result = await pool.query('INSERT INTO users set ?', [newUser]);
console.log(result);
}));
`
As you can see, I'm trying to print an "OkQuery" that says that everything went perfect.
But that's not the case because of this error.
`
Error
at Pool.query (/home/theivano/Escritorio/Personal/Practicas_Uni/TFG/myapp/node_modules/mysql/lib/Pool.js:199:23)
at Strategy.passport.use.LocalStrategy [as _verify] (/home/theivano/Escritorio/Personal/Practicas_Uni/TFG/myapp/src/lib/passport.js:22:31),
`
PD: the database receives the newUser correctly! I checked!

Could not get response when making POST request from Postman to Node.js (express), MySQL

I'm facing issues while making simple POST requests from NodeJS server running on localhost. Trying, to POST JSON format data from Postman to NodeJS with express storing data to MySQL. Using the MVC method of going through the Server -> Routes (will format the data) -> Controller (validation & strong to MySQL). Error handling was applied too. but no error showing on Terminal or Postman. I've might miss something on my routes I guess. Appreciate the help. Thanks in advance!
index.js
const express = require('express');
const authRoutes = require('./routes/auth');
const errorController = require('./controllers/error');
const app = express();
const PORT = 8080;
const ports = process.env.PORT || PORT;
// MIDDLEWEAR PARSE JSON DATA
app.use(express.json());
// HEADER ACCESS CONTROL, REQUEST, ROUTES
app.use((req, res, next) => {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader(
'Access-Control-Allow-Methods',
'GET, POST, PUT, DELETE, OPTIONS'
);
res.setHeader(
'Access-Control-Allow-Headers',
'Content-Type, Accept, X-Custom-Header, Authorization'
);
next();
});
// AUTH
app.use('/auth', authRoutes);
// PAGE NOT FOUND
app.use(errorController.get404);
// SERVER NOT RESPONDING
app.use(errorController.get500);
app.listen(PORT, () => {
console.log(`server started at port ${ports}`);
});
Routes/auth.js
const express = require('express');
const { body } = require('express-validator');
const router = express.Router();
const User = require('../models/user');
const authController = require('../controllers/auth');
router.post(
'/signup',
[
body('email')
.isEmail()
.withMessage('Please enter a valid email.')
.custom(async (email) => {
const user = await User.find(email);
if (user[0].length > 0) {
return Promise.reject('Email address already exist!');
}
})
.normalizeEmail(),
body('password').trim().isLength({ min: 7 }),
body('admin').not().isEmpty(),
],
authController.signup
);
module.exports = router;
controllers/auth.js
const { validationResult } = require('express-validator');
const bcrypt = require('bcryptjs');
const User = require('../models/user');
exports.signup = async (req, res, next) => {
const errors = validationResult(req);
if (!errors.isEmpty()) return;
const email = req.body.email;
const password = req.body.password;
const admin = req.body.admin;
try {
const hashedPassword = await bcrypt.hash(password, 12);
const userDetails = {
email: email,
password: hashedPassword,
admin: admin,
};
const results = await User.save(userDetails);
return res.status(201).json({ message: 'User registered!' });
} catch (err) {
if (!err.statusCode) {
return err.statusCode = 500;
}
next(err);
}
};
error.js
// ERROR MIDDLEWARE
exports.get404 = (req, res, next) => {
const error = new Error('Not found');
error.status = 404;
next(error);
};
exports.get500 = (error, req, res, next) => {
res.status(error.status || 500);
res.json({
error: {
message: error.message,
},
});
};
Models/users.js
const db = require('../util/database');
module.exports = class User {
constructor(email, password, admin) { // TODO: , admin
this.email = email;
this.password = password;
this.admin = admin;
}
static find(email) {
return db.execute('SELECT * FROM users WHERE email = ?', [email]);
}
static save(user) {
return db.execute('INSERT INTO users (email, password) VALUES (?, ?, ?)', [
user.email,
user.password,
user.admin,
]);
}
};
Postman
POST -> http://localhost:8080/auth/signup
{
"email": "joe#gmail.com",
"password": "password",
"admin": "admin"
}

Node callback returns mysql result but i cant print to the user with actions on google for dialogflow

I created an intent to get user information based on the ID he provides as param. Using a mysql module i can process the query and get the result. With a callback i can get the result to the main function but the agent ignores once i pass to a conv.ask(). What am i doing wrong?
This is my first script with node. I tried declaring pesquisar_aluno() in a variable so i could use in the main function but it retuns null.
const express = require('express');
const bodyParser = require('body-parser')
const mysql = require('mysql')
const {
dialogflow,
SignIn,
SimpleResponse
} = require('actions-on-google')
app.intent('pesquisar.alunos', (conv, params) => {
const aluno = params.aluno
conv.ask('Vamos pesquisar')
pesquisar_aluno(aluno,function(result){
var resposta = result
console.log(resposta) // returns the result
conv.ask(resposta) // ignores it
})
console.log(resposta) // returns undefined
})
function pesquisar_aluno(aluno,callback)
{
var connection = mysql.createConnection({
host : process.env.MYSQL_HOST,
user : process.env.MYSQL_USER,
password : process.env.MYSQL_PASS,
database : process.env.MYSQL_DB
})
connection.connect()
var query = `SELECT * FROM aluno WHERE id_aluno = "${aluno}"`
connection.query(query, function (error, results, fields)
{
if(error) throw error
var usuario = `RA =>${results[0].id_aluno} Nome => ${results[0].nome}`
if(callback) return callback(usuario)
})
}
Expect conv.ask(resposta) to print the result to the user but its not printing anything
Edit: Changed to promises. It worked!Thanks to Nick Felker and Prisoner
app.intent('pesquisar.alunos', (conv, params) => {
const aluno = params.aluno
conv.ask('Vamos pesquisar')
let nome = pesquisar_aluno_promise(aluno).then(function(results) {
return results[0].nome
}).catch((err) => setImmediate(() => { throw err; }))
return nome.then(function(result){
conv.ask(result)
})
})
async function pesquisar_aluno_promise(aluno)
{
return new Promise(function (resolve,reject) {
var connection = mysql.createConnection({
host : process.env.MYSQL_HOST,
user : process.env.MYSQL_USER,
password : process.env.MYSQL_PASS,
database : process.env.MYSQL_DB
})
connection.connect()
var query = `SELECT * FROM aluno WHERE id_aluno = "${aluno}"`
connection.query(query, function (error, results, fields)
{
if (error) {
return reject(error)
}
resolve(results)
})
})
}
As Nick suggested in the comments, you need to use Promises when you are doing asynchronous operations.
Additionally, however, you need to return that Promise from your Intent Handler so the Intent Dispatcher knows to wait for the result before continuing.
In your case, this can just be adding return, so it might look something like this:
return nome.then(function(result){
console.log(result) //works
conv.ask(result) //should work now
})

nodejs mysql post method return an old unknow record

i have problem with post method in mysql node js, when i post the request in postman it return an old record i don't know where come from.
in the first i used Get method and it worked very well but when i changed the method to Post i found thid problem.
i use this request for a form in react app i think the problem is not in the form because i tried the request in postman before try it in the app.
const express = require('express');
const cors = require('cors');
const mysql = require('mysql');
const bodyParser = require('body-parser')
const app = express();
// Connection Mysql
const selectQuery = 'SELECT * FROM userstab';
const connection = mysql.createConnection({
host : 'localhost',
user : 'root',
password : '',
database : 'nodeusers',
});
connection.connect(err => {
if (err) {
return err;
}
});
console.log(connection);
// Connection Express Body-Parser Cors
app.use(cors());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.get('/', (req, res) => {
res.send('Hello from the products server')
});
app.post('/userss/add', (req, res) => {
const nom = req.body.nom;
const prenom = req.body.prenom;
const adresse = req.body.adresse;
const email = req.body.email;
console.log(nom, prenom);
const insertQuery = `INSERT INTO userstab (nom, prenom, adresse,
email) VALUES
("${nom}","${prenom}","${adresse}",
"${email}")`;
connection.query(insertQuery,[nom,prenom,adresse,email],
(err,results) => {
if(err) {
res.send(err)
}
console.log(nom, prenom);
res.send({ error: false, data: results, message: 'user has
been added successfully.' });
})
});
// First Get request/////////////////////////////////////////
app.get('/userss/add', (req, res) => {
const { nom, prenom, adresse, email } = req.query;
const insertQuery = `INSERT INTO userstab (nom, prenom, adresse, email) VALUES ('${nom}','${prenom}','${adresse}','${email}')`;
connection.query(insertQuery, (err, results) => {
if(err) {
return res.send(err)
}
else {
return res.send('successfully added user')
}
});
});
////////////////////////////////////////////////////////////////////
app.listen(4000, () => {
console.log('Users server worked on port 4000...')
});
Because you are using users table in post request , and another table called userstab in get request.
So please change you query in post request to be the same table in get request.

Node loop insert with mySQL and Mongodb

I have a form with one field that allows user to enter multiple developer id via comma delimited (ab1234,bc5678).
Once the form is submitted I perform the following tasks:
Get the the project
Loop through array of developer IDs to get their full name using mySQL
update the project using MongoDB
I'm new and sure this this is possible, The codes I have below is not working for me. Can someone please let me know if the codes below is even close.
const mongoose = require('mongoose'
const mysql = require('mysql');
// Create mySQL connection
const mySQLdb = mysql.createConnection({
host : 'localhost',
user : 'root',
password : 'root',
database : 'projects'
});
const Project = mongoose.model('project');
router.post('/developerSave', async (req, res) => {
let devList = req.body.dev_ids,
devIdArr = devList.split(','),
rData = {};
// get project
const project = await Project.findById(req.body.projectID);
mySQLdb.connect();
for(var i=0, len=devIdArr.length; i < len; i++) {
let sql = `SELECT CONCAT(first_name, ' ', last_name) as full_name FROM users WHERE id= '${devIdArr[i]}'`;
mySQLdb.query(sql, function (err, results) {
if (err) throw err;
let newDev = {
userId: devIdArr[i],
fullName: results[0].full_name
}
project.developers.unshift(newDev);
await project.save();
});
}
mySQLdb.end();
rData.success = true;
rData.msg = 'Developer was added successfully.';
res.status(200).json(rData);
});
The reason you are seeing this is because your await project.save(); is inside the callback function. Your main function will not wait for all the callbacks to complete and close the db connection. Lets look at the example below
const myCallback = (param, callback) => {
setTimeout(() => {
console.log('callback function', param);
callback();
}, 1000)
}
const myAsync = async () => {
console.log('inside async');
const result = await axios.get('http://google.com/');
for (let i = 0; i < 10; i++) {
myCallback(i, () => {
console.log('this is the actual callback function');
});
}
const result2 = await axios.get('http://bing.com/');
console.log('after second call');
}
myAsync();
The output of this is
inside async
after second call
callback function 0
this is the actual callback function
...
As you can see, the after second call is printed before the callback functions.
To solve this problem, you can wrap your callback function in a promise and resolve that once save is complete.