Promise { <pending> } React bcrypt hashing the Password [duplicate] - node.js

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 9 months ago.
I am creating a Login/Registration Form Using Nodejs. I am hashing the password entered by the user using bcrypt.js but when I assign the password to a variable so that I push that to the database I get this error "Promise { pending }".
I am learning nodejs and react so I do not know too much about this can someone help me.
Thanks!
The Code That I am running is:
################################
const express = require('express');
const app = express();
const mysql = require('mysql2');
const bcrypt = require('bcryptjs');
const cors = require('cors');
// Need this to make api request from backend
app.use(cors());
/**using this express will format the data automatically in json format */
app.use(express.json()); /**Use This Otherwise you get the req.body undefined */
const port = 3001;
const securePassword = async (password) => {
const passwordHash = await bcrypt.hash(password, 4);
return passwordHash;
};
const db = mysql.createConnection({
user: 'root',
host: 'localhost',
password: 'newpassword',
database: 'INSTAGRAM',
});
// Getting Data From Signup Form of React
app.post('/signup', (req, res) => {
const emailaddress = req.body.emailaddress;
const fullname = req.body.fullname;
const username = req.body.username;
const password = req.body.password;
const hashPass = securePassword(password);
console.log(hashPass);
// Checking If Use Already Exist
db.query(
'SELECT * FROM USER WHERE username = ? OR email = ? ',
[username, emailaddress],
(err, result) => {
if (err) {
res.send({ err: err });
} else {
if (result.length > 0) {
res.send({ message: 'Username/Email Already Exist' });
} else {
db.query(
'INSERT INTO USER (username, fullname, email, password) VALUES (?, ?, ?, ?)',
[username, fullname, emailaddress, hashPass],
(err, result) => {
if (err) {
res.send(err);
} else {
res.send(result);
}
}
);
}
}
}
);
});
// Starting the server on port 3001
app.listen(port, () => {
console.log(`SERVER STARTED ${port}`);
});

First of all for better and more professional coding try to break your code into multiple functions in multiple .js files .
then you should pass a function to validate the inputs otherwise any data can be passed to db without being validated .
and then you can use this codes for user Registration :
app.js file :
const express = require('express');
const app = express();
const userRouter = require('./routes/user.routes');
app.use(express.json());
app.use('/user', userRouter);
user.routes file :
const express = require('express');
const userRouter = express.Router();
const {httpHandleSignUp} = require('../controllers/user/user.controller');
userRouter.post('/signup', httpHandleSignUp);
module.exports = userRouter
and then for handling Registration you can create a controller file and first of all check the inputs :
httpHandleSignUp controller code :
async function handleSignUp(req, res) {
const values = req.body
const errors = await validateInputs(values, res);
if(errors.length == 0) {
await addUserToDB(values, res);
} else {
res.json(errors)
}
}
you can use any validation you want like code below :
async function validateInputs(values, res) {
let errors = [];
if(!values.name || !values.email || !values.password) {
errors.push('missing required inputs');
}
if(!/\S+#\S+\.\S+/.test(values.email)) { // regex : string#string.string
errors.push('invalid email address ');
}
if(values.password.length < 8) {
errors.push('entered password is too short !');
}
if(await checkDbForEmail(values.email)) {
errors.push('a user with this email already registered !');
}
// TODO : add more validation
return errors;
}
and also you need to a function to check db for already registered users which used in above function :
async function checkDbForEmail(email) {
return await user.findOne({
email: email
});
}
now if there is NO errors the user will be added to DB by this function :
async function addUserToDB(values, res) {
bcrypt.hash(values.password, saltRounds)
.then(hashedPass => {
user.create({
name: values.name,
email: values.email,
password: hashedPass
}, (err, user) => {
res.json({
ok : 'user added to db successfully',
data: {
name: user.name,
email: user.email
}
});
});
})
.catch( (err) => console.log(err));
}
tip: this code works with mongo you may need to changes DB functions.

Related

jwtGenerator - invalid input syntax for type uuid: "{}"

i am trying to create login register page with using PERN Stack and jwt
i have a database(vetmed) which consist of
CREATE TABLE veterinaryInfo(
vetId uuid PRIMARY KEY DEFAULT
uuid_generate_v4(),
vetName VARCHAR(30) NOT NULL,
vetSurname VARCHAR(30) NOT NULL,
branch_Name VARCHAR(50) NOT NULL,
address VARCHAR(100) NOT NULL ,
email VARCHAR(30) NOT NULL,
phone VARCHAR(11) NOT NULL,
password VARCHAR(255) NOT NULL);
Here is my jwt.Auth.js code:
const express = require('express');
const router = express.Router();
const bcrypt = require('bcrypt');
const pool = require('../db');
const validInfo = require('../middleware/validInfo');
const jwtGenerator = require('../utils/jwtGenerator');
const authorization = require('../middleware/authorization');
//authorizeentication
router.post('/register', validInfo, async (req, res) => {
try {
//1. destructure the req.body ( )
const { name, surname, branch, address_, mail, phone_, password_ } =
req.body;
// 2. check if user exist ( if exist then throw error)
const user = await pool.query(
'SELECT * FROM veterinaryInfo WHERE email = $1',
[mail]
);
//res.json(user.rows);
if (user.rows.length !== 0) {
// user already exist
return res.status(401).send('user already exist');
}
// 3. Bcrypty the user password
const saltRound = 10;
const salt = await bcrypt.genSalt(saltRound);
const bcryptPassword = await bcrypt.hash(password_, salt);
// 4. enter the new user inside the database
let newUser = await pool.query(
'INSERT INTO veterinaryInfo(vetName, vetSurname, branch_Name,address,email,phone,password) VALUES ($1,$2,$3,$4,$5,$6,$7) RETURNING *',
[name, surname, branch, address_, mail, phone_, bcryptPassword]
);
//res.json(newUser.rows[0]);
// 5 generating our jwt token
const token = jwtGenerator(newUser.rows[0].vetId);
res.json({ token });
} catch (err) {
console.error(err.message);
res.status(500).send('server error');
}
});
//login route
router.post('/login', validInfo, async (req, res) => {
try {
// 1. destructure the req.body
const { name, surname, branch, address_, mail, phone_, password_ } =
req.body;
// 2. check if user doesn't exist (if not then throw error)
const user = await pool.query(
'SELECT * FROM veterinaryInfo WHERE email = $1',
[mail]
);
if (user.rows.length === 0) {
return res.status(401).json('Password or Email is incorrect');
}
// 3. check if incoming password is the same the database password
const validPassword = await bcrypt.compare(
password_,
user.rows[0].password
);
// console.log(validPassword);
if (!validPassword) {
return res.status(401).json('Password or Email is incorrect');
}
// 4. give them the twt token
const token = jwtGenerator(user.rows[0].vetId);
return res.json({ token });
} catch (err) {
console.error(err.message);
res.status(500).send('Server error');
}
});
router.get('/is-verify', authorization, async (req, res) => {
try {
res.json(true);
} catch (err) {
console.error(err.message);
res.status(500).send('server error');
}
});
module.exports = router;
In postman i can create a new register successfully, i can use login and is-verify method succesfully. However,
Here is my dashboard.js code :
const router = require('express').Router();
const authorization = require('../middleware/authorization');
const pool = require('../db');
router.get('/', authorization, async (req, res) => {
try {
const user = await pool.query(
'SELECT * FROM veterinaryInfo WHERE vetId = $1',
[req.user]
);
//res.json(user.rows[0]);
// res.json('hello');
res.json(user.rows[0]);
} catch (err) {
console.error(err.message);
res.status(500).send('Server error');
}
});
module.exports = router;
In postman with http://localhost:5000/dashboard/ when i write the token value on the header which relative to login and is-verify. i can not access the vetId from res.json(user.rows[0])
Here is my jwtGenerator.js code:
const jwt = require('jsonwebtoken');
require('dotenv').config();
//Look at file server/routes/dashboard.js to see the change code for this code
function jwtGenerator(vetId) {
const payload = {
user: vetId,
};
/*function jwtGenerator(vetId) {
const payload = {
user: {
id: vetId,
},
};*/
return jwt.sign(payload, process.env.jwtSecret, { expiresIn: '1h' });
}
module.exports = jwtGenerator;
authorization.js code :
const jwt = require('jsonwebtoken');
require('dotenv').config();
//this middleware will on continue on if the token is inside the local storage
module.exports = async (req, res, next) => {
try {
// Get token from header
const jwtToken = req.header('token');
// Check if not token
if (!jwtToken) {
return res.status(403).json('not authorize');
}
// Verify token
//it is going to give use the user id (user:{id: user.id})
const payload = jwt.verify(jwtToken, process.env.jwtSecret);
//console.log(jwtToken);
req.user = payload.user;
console.log(req.user);
next();
}catch (err) {
console.error(err.message);
res.status(403).json('not authorize');
}
};
index.js code :
const express = require('express');
const app = express();
const cors = require('cors');
app.use(express.json()); // req body
app.use(cors());
//ROUTES
//register and login routes
app.use('/auth', require('./routes/jwtAuth')); // activate routes
app.use('/dashboard', require('./routes/dashboard')); // dashboard route
app.listen(5000, () => {
console.log('server is running on port 5000');
});
the output is
[nodemon] restarting due to changes...
[nodemon] starting `node index index.js`
server is running on port 5000
{}
invalid input syntax for type uuid: "{}"

Node.js query not inserting data into Azure SQL database

Here is my code for my index.js. Now I made an express server to be able to use /register for my creating an account. All the data that I insert into front end is coming over fine.
I'm able to connect and see rows if I use a different code. And it goes to my query database just fine and all the values are fine, but it returns invalid column name and the column name returning is saying it is invalid and is the stuff I input on the front end. So am I doing something wrong with the SQL query in the index? The table is already made. Any help on what I'm doing wrong.
Like if I put test on the username and register it returns Invalid column name 'test'
const express = require("express");
const cors = require("cors");
const app = express();
app.use(express.json({
type: ['application/json', 'text/plain']
}));
app.use(cors());
const { Connection, Request } = require("tedious");
// Create connection to database
const config = {
authentication: {
options: {
userName: "username", // update me
password: "password" // update me
},
type: "default"
},
server: "dragonfitness.database.windows.net", // update me
options: {
database: "dragonfitness", //update me
encrypt: true
}
};
const connection = new Connection(config);
// Attempt to connect and execute queries if connection goes through
connection.on("connect", err => {
if (err) {
console.error(err.message);
} else {
console.log("Server Running and Connected")
}
});
app.post("/register", (req, res)=> {
const firstname = req.body.firstname;
const lastname = req.body.lastname;
const username = req.body.username;
const password = req.body.password;
const email = req.body.email;
queryDatabase(firstname, lastname, username, password, email);
})
connection.connect();
function queryDatabase(firstname, lastname, username, password, email ) {
console.log("testing");
var sql = "INSERT dbo.user_info(first_name, last_name, user_name, password, email) VALUES ("+firstname+", "+lastname+", "+username+", "+password+", "+email+")"
console.log('query========='+sql)
// Read all rows from table
const request = new Request(sql,
(err, result) => {
if (err) {
console.error(err.message);
} else {
console.log('worked');
}
}
);
connection.execSql(request);
}
app.listen(1433, () => {
console.log("running server");
});
Instead of concatenating string values in your sql commands, you should use Parametrized Queries.
See the following example:
function inputParameters() {
// Values contain variables idicated by '#' sign
const sql = `INSERT INTO ${table} (uniqueIdCol, intCol, nVarCharCol) VALUES (#uniqueIdVal, #intVal, #nVarCharVal)`;
const request = new Request(sql, (err, rowCount) => {
if (err) {
throw err;
}
console.log('rowCount: ', rowCount);
console.log('input parameters success!');
outputParameters();
});
// Setting values to the variables. Note: first argument matches name of variable above.
request.addParameter('uniqueIdVal', TYPES.UniqueIdentifier, 'ba46b824-487b-4e7d-8fb9-703acdf954e5');
request.addParameter('intVal', TYPES.Int, 435);
request.addParameter('nVarCharVal', TYPES.NVarChar, 'hello world');
connection.execSql(request);
}

errors generated by express validator with node express [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 2 years ago.
Improve this question
I am using nodejs, express, & express-validator. I am trying to use express validator on my sign_up page . Express-validator generates the errors in an array of objects.
the error:
Result {
formatter: [Function: formatter],
errors: [
{
value: undefined,
msg: 'Please Enter a Valid Username',
param: 'username',
location: 'body'
},
{
value: undefined,
msg: 'Please enter a valid email',
param: 'email',
location: 'body'
},
{
value: undefined,
msg: 'Please enter a valid password',
param: 'password',
location: 'body'
}
]
}
I use postman to test the register operation
and send the following in the request:
{
"username":"ruba",
"email":"test#gmail.com",
"password":"1234544545#"
}
my user.js code:
// Filename : user.js
const express = require("express");
const { check, validationResult} = require("express-validator");
const bcrypt = require("bcryptjs");
const jwt = require("jsonwebtoken");
const router = express.Router();
const User = require("../model/User");
/**
* #method - POST
* #param - /signup
* #description - User SignUp
*/
router.post(
"/signup",
[
check("username", "Please Enter a Valid Username")
.not()
.isEmpty(),
check("email", "Please enter a valid email").isEmail(),
check("password", "Please enter a valid password").isLength({
min: 6
})
],
async (req, res) => {
const errors = validationResult(req);
console.log(errors);
if (!errors.isEmpty()) {
console.log("error sign");
return res.status(400).json({
errors: errors.array()
});
console.log("error sign2");
}
console.log("error sign3");
const {
username,
email,
password
} = req.body;
try {
let user = await User.findOne({
email
});
if (user) {
return res.status(400).json({
msg: "User Already Exists"
});
}
user = new User({
username,
email,
password
});
const salt = await bcrypt.genSalt(10);
user.password = await bcrypt.hash(password, salt);
await user.save();
const payload = {
user: {
id: user.id
}
};
jwt.sign(
payload,
"randomString", {
expiresIn: 10000
},
(err, token) => {
if (err) throw err;
res.status(200).json({
token
});
}
);
} catch (err) {
console.log(err.message);
res.status(500).send("Error in Saving");
}
}
);
module.exports = router;
my index code:
const express = require("express");
const bodyParser = require("body-parser");
const user = require("./routes/user"); //new addition
const InitiateMongoServer = require("./config/db");
// Initiate Mongo Server
InitiateMongoServer();
const app = express();
// PORT
const PORT = process.env.PORT || 4000;
// Middleware
//app.use(bodyParser.json());
app.use(express.json());
app.get("/", (req, res) => {
res.json({ message: "API Working" });
});
app.use("/user", user);
app.listen(PORT, (req, res) => {
console.log(`Server Started at PORT ${PORT}`);
});
so please help me. what is the problem??
Edit: It's solved. the problem was in the postman settings (the contents type must be JSON)
Did you enabled
app.use(express.json());
Because I cant see any kind of problem with you code (about the express-validator).
I suggest you after this fix, you to change check to body since you wants only to check the content of body.
I'm using an middleware to helps to me keep my code short and legible, and I'll share with you
function validation(validations: Array<ValidationChain>) {
return async (req: Request, _res: Response, next: NextFunction) => {
await Promise.all(validations.map((v) => v.run(req)));
const errors = validationResult(req);
if (errors.isEmpty()) {
return next();
}
const msg = errors
.array()
.map((er) => `${er.param}`)
.join(', ');
const issue = new Issue(400, `missing or invalid params: ${msg}`);
next(issue);
};
}
The usage:
router.post(
'/login',
validation([body('email').isEmail(), body('password').isLength({ min: 5, max: 30 })]),
async (req: Request, res: Response, next: NextFunction): Promise<void> => {
...
});
``'

Can't get a response from my server. Why?

I can't get a response from my server. I am using postman and running the following post request:
localhost:4000/users/register?email=test#gmail.com&f_name=testf&s_name=tests&password=test
It hangs for a very long time and then says:
Could not get any response
This is my code:
[user.route.js]
const express = require('express');
const userRoutes = express.Router();
const cors = require('cors');
const bcrypt = require('bcryptjs');
const jwt = require('jsonwebtoken');
//require User model in the routes module
let User = require('../models/user.model.js');
//Make router use cors to avoid cross origin errors
userRoutes.use(cors);
//secret
process.env.SECRET_KEY = 'secret';
//define register route
userRoutes.post('/register', (req, res) => {
const today = new Date();
const userData = {
email: req.body.email,
f_name: req.body.f_name,
s_name: req.body.s_name,
password: req.body.password,
created: today
}
//Find one user based on email, hash their password and then create a document in the collection for that user
User.findOne({
email: req.body.email
})
.then(user => {
if (!user) {
bcrypt.hash(req.body.password, 10, (err, hash) => {
user.password = hash;
User.create(userData)
.then(user => {
res.json({
status: user.email + ' registered'
});
})
.catch(err => {
res.send('error: ' + err);
});
});
}
});
});
userRoutes.post('/login', (req, res) => {
User.findOne({
email: req.body.email
})
.then(user => {
if (user) {
if (bcrypt.compareSync(req.body.password, user.password)) {
const payload = {
_id: user._id,
f_name: user.f_name,
s_name: user.s_name,
email: user.email
}
let token = jwt.sign(payload, process.env.SECRET_KEY, {
expiresIn: 1440
});
res.send(token);
} else {
res.json({
'Error': 'Password Incorrect'
});
}
} else {
res.json({
'Error': 'User does not exist'
});
}
})
.catch(err => {
res.send('Error: ' + err);
});
});
module.exports = userRoutes;
[user.model.js]
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
let User = new Schema({
email: {
type: String
},
f_name: {
type: String
},
s_name: {
type: String
},
password: {
type: String
},
created: {
type: String
}
}, {
collection: 'users'
});
[server.js]
const express = require('express');
const app = express();
const bodyParser = require('body-parser');
const PORT = 4000;
const cors = require('cors');
const mongoose = require('mongoose');
const config = require('./db.js');
mongoose.Promise = global.Promise;
mongoose.connect(config.DB, {
useNewUrlParser: true
}).then(
() => {
console.log('Database is connected')
},
err => {
console.log('Can not connect to the database' + err)
}
);
app.use(cors());
app.use(bodyParser.urlencoded({
extended: true
}));
app.use(bodyParser.json());
var Users = require('./routes/user.route');
//make /users use routes
app.use('/users', Users);
app.listen(PORT, function() {
console.log('Server is running on Port:', PORT);
});
[db.js]
module.exports = {
DB: 'mongodb://localhost:27017/pharaohcrud'
}
I'm using Node, MongoDB, Mongoose, Vue, Express.
I'm new to Node in general so it's hard for me to give details on what i've done. Please feel free to ask any questions that you need answered to help me with issue and ill answer as thoroughly as i can :)
EDITS:
Here is the updated db.js file
module.exports = {
DB: 'mongodb://localhost:27017/pharaoh'
}
Here is the updated post request that im sending to the server through postman:
localhost:4000/users/register
[raw json request]
{
"email": "test#gmail.com",
"f_name": "test",
"s_name": "test",
"password": "test"
}
You have to send json data with your post request not query strings.
In postman, select "Body" tab and choose "raw" and from the dropdown menu select "json" format. Send your user data as Json, this will solve the issue.
Image description here
I went deleted all database-related code and retyped it, and now it works. I guess the lesson here is to always pay attention while typing code to make sure you're writing it correctly.

How to push and error from mongodb routes to validator, user signup form

I have a user sign up page in react, if a user tries to signup with an already taken screenname I get a mongodb error, since i set the scheme to screenname unique, Im validating the form using validator, how can i push "this username has already been taken" in errors.screenname in my validator file
/validator.js :
const isEmpty = require('lodash/isEmpty');
const validator = require('validator');
function validateInput(data) {
let errors = {};
if(validator.isEmpty(data.screenname)) {
errors.screenname = 'This field is require';
}
if(validator.isEmpty(data.email)) {
errors.email = 'This field is require';
}
if(!validator.isEmail(data.email)){
errors.email = 'Email is not valid!';
}
if(validator.isEmpty(data.password)) {
errors.password = 'This field is require';
}
if (!validator.equals(data.password, data.passwordConfirmation)){
errors.passwordConfirmation = 'Passwords must match!';
}
if(validator.isEmpty(data.passwordConfirmation)) {
errors.passwordConfirmation = 'This field is require';
}
return{
errors,
isValid: isEmpty(errors)
}
}
module.exports = validateInput;
User route file :
const express = require('express');
const bcrypt = require('bcrypt');
const UserDB = require('../../model');
const commonValidations = require('./shared/validation/signupvalidation');
const Promise = require('bluebird');
const isEmpty = require('lodash/isEmpty');
var mongoose = require('mongoose');
// mongoose.connect("mongodb://localhost:27017/RockfellerDB");
var db = mongoose.connection;
let router = express.Router();
function validateInput(data, otherValidations) {
let { errors } = otherValidations(data);
return Promise.all([
router.get('/', function(req, res){
UserDB.find({ screenname: data.screenname }).then(user => {
if (user) { errors.screenname = 'This username is already taken' }
})
})
]).then(() => {
return {
errors,
isValid: isEmpty(errors)
}
})
}
router.post('/', (req, res) => {
validateInput(req.body, commonValidations).then(({ errors, isValid }) => {
// if form is Valid we send it to our mongo database
if (isValid){
const password_digest = bcrypt.hashSync(req.body.password, 10);
var newUser = new UserDB({
screenname : req.body.screenname,
email: req.body.email,
password: password_digest
})
newUser.save(function(err, doc){
if (err) {
console.log(err);
} else {
res.send(doc);
}
});
} else {
res.status(400).json(errors);
}
})
});
module.exports = router;
return router;

Resources