Can't redirect after Mongoose query - node.js

I am trying to create a website with user accounts.
But can't redirect after Mongoose save query in register page.
Here is NodeJS index.js file
const express = require('express')
const app = express();
const cors = require('cors');
const mongoose = require('mongoose');
const CryptoJS = require('crypto-js');
const jwt = require('jsonwebtoken');
const dotenv = require('dotenv');
const User = require('./models/User');
dotenv.config();
app.set('view engine', 'ejs');
app.use(cors());
app.use(express.urlencoded({extended: true}));
app.use(express.json());
app.use(express.static('public'));
app.use(express.static('partials'));
app.use(express.static('images'));
app.use(express.static('assets'));
mongoose.connect(process.env.MONGO_URL)
.then(() => {
console.log('DB is connected');
})
.catch((err) => {
console.log(err);
});
app.post('/register', async (req, res) => {
const newUser = new User({
email: req.body.email,
password: CryptoJS.AES.encrypt(req.body.password, process.env.PASS_SEC).toString()
})
try {
const savedUser = await newUser.save();
res.redirect('/')
} catch (err) {
console.log(err)
}
})
(of course app.get('/') and app.get('/login') exists in my index.js file)
My register page (register.ejs)
<%- include('./partials/header') %>
<div class='container'>
<div class="login">
<h1 class='heading'>Register</h1>
<div class='form-block'>
<form action="/register" method="POST">
<label class='label'>Email</label>
<input class='input' type='email' name='email' placeholder='example#mail.com' required/>
<label class='label'>Password</label>
<input class='input' type='password' name='password' placeholder='********' required/>
<input class='button' type='submit' value='Sign Up' />
</form>
</div>
</div>
</div>
<%- include('./partials/footer') %>
Instead of redirect to main page I get json data of saved User.
How to fix that?

Related

Cookie error in node.JS app with next.js client program

I am actually write a node.JS application on natours project. It is actually a course project that was designed by jonas. I am designing a next.JS client side program of this backend program. Problem was that when I submit a request on http://localhost:3000/api/v1/users/signup url everything is ok, cookie is set but when I send a request on others url on this server like http://localhost:3000/api/v1/tours cookie is not read by the server and req.cookies is null. I am trying to solve this problem but I am stuck.
app.js Code
const express = require("express");
const morgan = require("morgan");
const bodyParser = require("body-parser");
const rateLimit = require("express-rate-limit");
const helmet = require("helmet");
const xss = require("xss-clean");
const mongoSanitize = require("express-mongo-sanitize");
const hpp = require("hpp");
const cors = require("cors");
const cookieParser = require("cookie-parser");
const globalErrorHandler = require("./controllers/errorController");
const tourRouter = require("./routes/tourRoutes");
const userRouter = require("./routes/userRoutes");
const reviewRouter = require("./routes/reviewRoutes");
const AppError = require("./utils/appError");
const app = express();
app.set("view engine", "pug");
app.set("views", `${__dirname}/views`);
// GLOBAL MIDDLEWARE
if (process.env.NODE_ENV === "development") {
app.use(morgan("dev"));
}
const limiter = rateLimit({
max: 100,
windowMs: 60 * 60 * 1000,
message: "Too many requests from this IP, Please try again in an hour.",
});
app.use(cors({ credentials: true, origin: "http://localhost:3001" }));
app.use(helmet());
app.use(xss());
app.use("/api", limiter);
app.use(cookieParser());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json({ limit: "10kb" }));
app.use(express.static(`${__dirname}/public`));
app.use(mongoSanitize());
app.use(
hpp({
whitelist: [
"duration",
"ratingsQuantiry",
"ratingsAverage",
"difficulty",
"maxGroupSize",
"price",
],
})
);
app.use((req, res, next) => {
req.requestTime = Date.now();
console.log(req.cookies.jwt);
next();
});
app.get("/", (req, res) => {
res.status(200).render("base", {
title: "Natours",
});
});
app.use("/api/v1/tours", tourRouter);
app.use("/api/v1/users", userRouter);
app.use("/api/v1/reviews", reviewRouter);
app.all("*", (req, res, next) => {
// res.status(404).json({
// status: "fail",
// message: `Can't find ${req.originalUrl} on ther server.`,
// });
const err = new AppError(
`Can't find ${req.originalUrl} on ther server.`,
404
);
next(err);
});
app.use(globalErrorHandler);
module.exports = app;
Client Code in Next.js
import React, { useState } from "react";
import axios from "axios";
import Layout from "../components/Layout";
const url = "http://localhost:3000/api/v1/users/signup";
const styles = {
"input-group": "flex flex-col gap-3",
"input-label": "px-2 text-md font-thin",
"text-input": "px-2 py-4",
button:
"px-4 py-3 font-thin uppercase text-md bg-teal-700 hover:bg-teal-600 text-slate-50 rounded-sm",
"cancle-button": "bg-red-700 hover:bg-red-600",
};
function Register() {
const [formData, setFormData] = useState({
name: "",
email: "",
password: "",
passwordConfirm: "",
photo: "",
});
const handleChange = (event) => {
setFormData({
...formData,
[event.target.name]: event.target.value,
});
};
const handleSubmit = async (event) => {
event.preventDefault();
axios
.post("http://localhost:3000/api/v1/users/signup", formData, {
withCredentials: true,
})
.then((response) => console.log(response))
.catch((err) => console.log(err));
alert(JSON.stringify(formData));
};
const handleReset = (event) => {
setFormData({
name: "",
email: "",
password: "",
passwordConfirm: "",
photo: "",
});
};
return (
<Layout>
<div className="p-10 bg-slate-50">
<form onSubmit={handleSubmit}>
<h1 className="text-2xl mb-5 text-teal-700">Register your account</h1>
<div className="w-1/2 flex flex-col gap-3">
<div className={styles["input-group"]}>
<label className={styles["input-label"]}>Name</label>
<input
className={styles["text-input"]}
placeholder="Enter your name"
type="text"
name="name"
value={formData.name}
onChange={handleChange}
required
/>
</div>
<div className={styles["input-group"]}>
<label className={styles["input-label"]}>Email</label>
<input
className={styles["text-input"]}
placeholder="Enter your email"
type="email"
name="email"
value={formData.email}
onChange={handleChange}
required
/>
</div>
<div className={styles["input-group"]}>
<label className={styles["input-label"]}>Password</label>
<input
className={styles["text-input"]}
placeholder="Enter your password"
type="password"
name="password"
value={formData.password}
onChange={handleChange}
required
/>
</div>
<div className={styles["input-group"]}>
<label className={styles["input-label"]}>Confirm Password</label>
<input
className={styles["text-input"]}
placeholder="Enter your confirm password"
type="password"
name="passwordConfirm"
value={formData.passwordConfirm}
onChange={handleChange}
required
/>
</div>
</div>
<div className="bg-slate-100 flex gap-3 mt-5 px-3 py-6 w-1/2">
<button className={styles.button} type="submit">
Register
</button>
<button
className={`${styles.button} ${styles["cancle-button"]}`}
type="reset"
onClick={handleReset}
>
Cancle
</button>
</div>
</form>
</div>
</Layout>
);
}
export default Register;

How to find whether user has signed up before login, in react, node and mariadb

I am new to react and mariaDB and this is my first attempt. I have created a sign up and sign in form in a single page. I used reactjs for frontend and node for backend and used mariaDB as database. I was able to insert username and password to databse when sign up. Now I want to check whether user has signed up when user try to login. I want to display an error as Wrong combination when username and password is not matched with registered users. I tried to display it, but it doesn't work.
here is my app.js in client side ,
import React, { useState } from 'react';
import './App.css';
import Axios from "axios";
function App() {
const [usernameReg,setUsernameReg]= useState("");
const [passwordReg,setPasswordReg]= useState("");
const [username,setUsername]= useState("");
const [password,setPassword]= useState("");
const [loginStatus,setLoginStatus]= useState("");
const register = () => {
Axios.post("http://localhost:3001/register", {
username:usernameReg,
password:passwordReg,
}).then((response) => {
console.log(response);
});
};
const login = () => {
Axios.post("http://localhost:3001/login", {
username:username,
password:password,
}).then((response) => {
if(response.data.message){
setLoginStatus(response.data.message);
}
else{
setLoginStatus(response.data[0].username);
}
});
};
return (
<div className="App">
<div className='registration'>
<label>Username</label>
<br/>
<input type="text" onChange={(e)=>{
setUsernameReg(e.target.value)
}}>
</input>
<br/>
<label>Password</label>
<br/>
<input type="text" onChange={(e)=>{
setPasswordReg(e.target.value)
}}>
</input>
<br/>
<button onClick={register}>Register</button>
<br/>
</div>
<div className='login'>
<br/>
<label>Username</label>
<br/>
<input type="text"
onChange={(e)=>{
setUsername(e.target.value)
}}
></input>
<br/>
<label>Password</label>
<br/>
<input type="text"
onChange={(e)=>{
setPassword(e.target.value)
}}
></input>
<br/>
<button onClick={login}>Login</button>
</div>
<h1>{loginStatus}</h1>
</div>
);
}
export default App;
here is my index.js in server side
const express = require("express");
const mariadb = require("mariadb");
const cors = require("cors");
const bodyParser = require("body-parser");
const app = express();
app.use(cors());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(express.json());
const db = mariadb.createPool({
user: "root",
host: "localhost",
password: "NishR",
database: "pedro",
});
app.post("/register", async (req, res) => {
const username= req.body.username;
const password = req.body.password;
db.query(
"INSERT INTO user (username,PASSWORD) VALUES(?,?)",
[username,password],
(err,result)=>{
console.log(err);
}
);
}
);
app.post("/login", async (req, res) => {
const username= req.body.username;
const password = req.body.password;
db.query(
"SELECT * FROM user WHERE username=? AND password=?",
[username,password],
(err,result)=>{
if (err){
res.send({err:err});
}
if(result.length>0){
res.send(result);
}else{
res.send({message:"wrong combination"});
}
}
);
}
);
app.listen(3001, () => {
console.log("Server is running");
});
please help me to find the error.

Req.body is empty and also cannot read property path of undefined

My project was working fine till last week and now all of a sudden my post requests are not working . i tried all methods and read other questions of stack overflow but was unable to fix the issue . can some one please help me?
Issue : req.body is undefined and also whenever i try upload a file "cannot read property path of undefined" is the error.
i'm using express middle ware to parse the request body . i also have my form enctype to multipart/form-data..
Code snippet is below :
require('dotenv').config()
const express = require('express');
const app = express();
const router = express.Router();
const session = require('express-session');
const fs = require(`fs`);
const mysql = require(`mysql-await`);
const path = require('path');
app.set('view engine', 'ejs');
app.set('views', path.join(__dirname, 'views'));
app.use(express.static(path.join(__dirname, 'public')));
app.use(express.json())
app.use(express.urlencoded({ extended: true }))
const multer = require('multer');
const {storage} = require('../cloudinary');
const upload = multer({storage});
const con = mysql.createConnection({
host: "localhost",
user: "root",
password: "Sujanya#1978",
database: "dept"
});
con.connect((err) => {
if (!err) {
console.log("Connected");
}
else {
console.log(err)
}
})
router.get('/naaccircular',(req,res)=>{
(async () => {
let results = await con.awaitQuery('select* from dept.naaccircular;');
res.render('Naac_circular',{Egs : results})
})();
})
router.get('/naaccriteria',(req,res)=>{
(async () => {
flet results = await con.awaitQuery('select* from dept.naaccriteria;');
res.render('Naac_criteria_files',{Fgs : results})
})();
})
router.post('/naacaddcircular',upload.single('circularfile'),(req,res) => {
console.log(req.body);
const n = req.body.circularname;
const d = req.body.circulardate;
const l = req.file.path;
con.connect(function(err){
var records = [n,d,l];
con.query("insert into dept.naaccircular (cirname,cirlink,cirdate)
VALUES (?,?,?)", [n,l,d] , function (err, result, fields){
if (err) throw err;
})
});
console.log(n);
console.log(l);
console.log(d);
res.redirect('/naaccircular');
})
module.exports = router;
style="margin-top:80px; background-color: white;">
<form action="/naacaddcircular" method="POST" class="row g-3 form-container" enctype="multipart/form-data">
<h3 style="text-align: center;">Naac Circular</h3>
<div class="mb-3">
<label for="ii" class="form-label">Name</label>
<input id="ii" name="circularname" class="form-control" type="text" placeholder="Default input"
aria-label="default input example">
</div>
<div class="mb-3">
<label for="jj" class="form-label">Date</label>
<input id="jj" name="circulardate" class="form-control" type="date">
</div>
<div class="input-group mb-2">
<input type="file" class="form-control" name="circularfile"id="inputGroupFile04" aria-describedby="inputGroupFileAddon04"
aria-label="Upload">
<!--<button class="btn btn-outline-secondary" type="button" id="inputGroupFileAddon04">Button</button>-->
</div>
<button type="submit"
class="btn btn-primary position-relative start-50 botttom-0 translate-middle-x">Upload</button>
</form>
</div> ```
The problem is with cloudinary module. I have rectified it, there are no errors in the post method.
Once upload.single() function is removed from the router.post() function I'm able to get the req.body(),

Body parser returning undefined for req.body request (SIMPLE LOGIN for beginner)

So I installed body parser via
npm i install express body-parser
and I wrote a simple code designed to input a user into an array after they complete a registration form.
but when I console.log the user it returns undefined for both email and password
here is the server code
const express = require('express');
const path = require('path');
const app = express();
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
const PORT = 3000;
var Users = [{"email":"mike#gmail.com", "password":"456"}];
app.get('/', (req, res) => {
res.render('index.ejs')
})
app.get('/Register.ejs', (req, res) => {
res.render('Register.ejs')
})
app.post('/views/Register.ejs', (req, res) =>
{
const newUser = {
email: req.body.email,
password: req.body.password
};
Users.push(newUser);
res.json(req.body.email);
console.log(Users)
}
)
app.listen(PORT);
here is the html for the register page
<h1>Please Register</h1>
<body>
<form action="/views/Register.ejs" method="POST">
<div class="div">
<label for="email">Enter Email</label>
<input type="email" id="email"for="email" id="email" required>
</div>
<div class="div">
<label for="password">Enter new password</label>
<input type="password" for="password" id="password" required>
</div>
<button type="submit"> Register </button>
</form>
</body>
Only installing body-parser is not enough. You have to put them in the code as middleware.
Top of the code use:
var bodyParser = require('body-parser');
and then use the code in somewhere middle of the code:
app.use(bodyParser.json())

'req.body.username' and 'req.body.password' are undefined [duplicate]

This question already has answers here:
req.body not populating with form data
(2 answers)
Closed 4 years ago.
I am creating login-register system in my project, actually I made it in many of my previous projects but this time I am getting an error, for which I've seen many posts related to this but none of them worked for me.
This is my code:
app.js
const express= require('express');
const mongoose= require('mongoose');
const bodyParser= require('body-parser');
const exphbs= require('express-handlebars');
const path= require('path');
const methodOverride= require('method-override');
const session= require('express-session');
const flash= require('connect-flash');
const app= express();
const port= process.env.PORT || 8000;
mongoose.Promise= global.Promise;
mongoose.connect(process.env.MONGODB_URI ||
'mongodb://localhost:27017/chat',{ useNewUrlParser: true });
app.use(express.static(path.join(__dirname, 'public')));
//body-parser
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended:true}));
//View engine
app.engine('.hbs', exphbs({extname: '.hbs'}));
app.set('view engine', '.hbs');
//Load Routes
const index= require('./routes/index');
//Use routes
app.use('/',index);
app.listen(port,()=> {
console.log(`Started on port ${port}`);
})
routes.index.js
const express = require('express');
const router = express.Router();
const bcrypt= require('bcryptjs');
const {User}= require('../models/User');
router.all('/*',(req,res,next)=> {
req.app.locals.layout= 'layout';
next();
})
router.get('/login',(req,res,next)=> {
res.render('routes_UI/login');
})
router.get('/signup',(req,res,next)=> {
res.render('routes_UI/signup');
})
router.post('/signup',(req,res)=> {
let errors=[];
if(req.body.password!==req.body.confirmPassword){
errors.push({message:'Passwords do not match'});
}
if(errors.length>0){
res.render('routes_UI/signup',{errors});
}else{
User.findOne({ username: req.body.username}).then((user)=> {
if(user){
req.flash('error_message',`A user with this username already exists`);
res.redirect('/signup');
}else{
bcrypt.genSalt(10, function(err, salt) {
bcrypt.hash(req.body.password, salt, function(err, hash) {
const user= new User({
username:req.body.username,
password:hash,
});
user.save().then(()=> {
req.flash('success_message',`You have
registered successfully, please login`);
res.redirect('/login');
});
});
});
}
})
}
})
module.exports = router;
routes_UI.signup.hbs in views folder
<div class="card card-register mx-auto mt-5">
<div class="card-header">Register an Account</div>
<div class="card-body">
<form action="/signup" method="post" enctype="multipart/form-data">
<div class="form-group">
<label for="username">Username</label>
<input name="username" class="form-control" id="username" type="text" aria-describedby="username" placeholder="Enter username">
</div>
<div class="form-group">
<label for="exampleInputPassword1">Password</label>
<input name="password" class="form-control" id="exampleInputPassword1" type="password" placeholder="Password">
</div>
<div class="form-group">
<label for="exampleConfirmPassword">Confirm password</label>
<input name="confirmPassword" class="form-control" id="exampleConfirmPassword" type="password" placeholder="Confirm password">
</div>
<button type="submit" class="btn btn-primary btn-block">Register</button>
</form>
<div class="text-center">
<a class="d-block small mt-3" href="/login">Login Page</a>
<a class="d-block small" href="/">Home Page?</a>
</div>
</div>
</div>
Error that I obtained is-
(node:2468) UnhandledPromiseRejectionWarning: ValidationError: users
validation failed: username: Path `username` is required., password: Path
`password` is required.
at new ValidationError (C:\Users\DEEPAK\chat-app-
1\node_modules\mongoose\lib\error\validation.js:30:11)
at model.Document.invalidate (C:\Users\DEEPAK\chat-app-
1\node_modules\mongoose\lib\document.js:2064:32)
at p.doValidate.skipSchemaValidators (C:\Users\DEEPAK\chat-app-
1\node_modules\mongoose\lib\document.js:1927:17)
at C:\Users\DEEPAK\chat-app-1\node_modules\mongoose\lib\schematype.js:896:9
at process._tickCallback (internal/process/next_tick.js:61:11)
(node:2468) UnhandledPromiseRejectionWarning: Unhandled promise rejection.
This error originated either by throwing inside of an async function
without a catch block, or by rejecting a promise which was not handled with
.catch(). (rejection id: 1)
(node:2468) [DEP0018] DeprecationWarning: Unhandled promise rejections are
deprecated. In the future, promise rejections that are not handled will
terminate the Node.js process with a non-zero exit code.
User model
const mongoose= require('mongoose');
const UserSchema= new mongoose.Schema({
username:{
type: String,
required: true
},
password:{
type: String,
required: true
}
})
const User= mongoose.model('users', UserSchema);
module.exports={User};
Thanks in advance
//body-parser
app.use(function(req, res, next)
app.use(bodyParser.urlencoded({extended:true}));
The above first line of code is incomplete and unnecessary. To correctly initialize body parser you can simply do the following as pointed out in the documentation.
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }))
// parse application/json
app.use(bodyParser.json())
You're missing the main body-parser directive:
app.use(bodyParser.json())

Resources