POST request from handlebars form gives 404 - node.js

I have the following form in my handlebars code:
{{#if contact}}
<form method="POST" action="/contacts/{{contact._id}}">
<input type="text" name="name">
<input type="text" name="phone">
<button>Update Contact</button>
</form>
{{else}}
When the user clicks the button, my browser is redirected to 'localhost:3000/contacts/34634234'
and I get a 404 error.
I checked, and 34634234 is a valid ID.
In my Node routes, I have
router.post('contacts/:id', function(req, res) {
res.render('index');
});
I know res.render('index') works because I've used it in other parts of my code.
However,

Not sure if is because of this, but...
You're missing type="submit" on the button element.
{{#if contact}}
<form method="POST" action="/contacts/{{contact._id}}">
<input type="text" name="name">
<input type="text" name="phone">
<button type="submit">Update Contact</button>
</form>
{{else}}
And you're missing a slash / at the beginning of your route.
router.post('/contacts/:id', function(req, res) {
res.render('index');
});

Related

GET not able to handle Redirect in Nodejs

So, I have this POST method in NodeJS that handles the login authentication
// Login logic
app.post("/home", function(req, res){
Item.findOne({EmailID: req.body.emailAddress}, function (err, docs) {
if(req.body.emailAddress === docs.EmailID && hash(req.body.password, docs.Salt) === docs.Password) {
currentUser = docs.FirstName;
console.log("Damn");
res.redirect("dashboard.html");
}
});
});
I can see in the console that "Damn" is printed, but for some reason, the redirect doesn't go to the following GET "dashboard.html" method as it is supposed to go but rather goes to the 404 error function
app.get("/dashboard.html", (req, res)=>{
console.log("here we go again");
Activity.find({}, function(err, foundItems){
res.render("home", {newListItems: foundItems});
});
});
and instead goes to the following 404 function. "here we go again" doesn't print on the console. Any idea on how to make the redirect go to the get function?
app.get("/*", function(req, res){
res.sendFile(__dirname + "/404.html")
});
This is my HTML
<form class="" action="/home" method="post">
<div class="">
<img class ="tent-image"src="assets/images/tent.png" alt width="90" height="72">
<h4 class="company">PASTIME</h4>
<h1 class="h3 mb-3 fw-normal"> Sign in</h1>
<h4 class="h3 fw-normal" style="color: <%= inputcolor %>"> <%= FirstLine %><br /> <%= SecondLine%> </h4>
<label for="inputEmail" class="virtually-hidden"></label>
<input id="inputEmail" name="emailID" class="form-control" placeholder="Email address" required="" autofocus="">
<label for="inputPassword" class="visually-hidden">Password</label>
<input type="password" name="passWORD" id="inputPassword" class="form-control" placeholder="Password" required="">
<div class="checkbox mb-3">
<label>
<input type="checkbox" value="remember-me"> Remember me
</label>
</div>
<button class="btn btn-dark" type="submit">Submit</button>
<p class="mt-5 mb-3 text-muted">© 2021 Pastime</p>
</form>
Please help
try by using
res.redirect("/dashboard.html");

My form is not correctly taking the route

I have this weird issue and it seems that I can't resolve it.
Whenever I submit my form, it goes to a "double route".
This is my html form.
<form action="eveniment/<%=eveniment._id%>" method="POST" id="modificaeveniment">
<input type="text" placeholder="titlu eveniment" name="titlu" value="<%= eveniment.name %>">
<button class="btn btn-info">Submit</button>
</form>
This is the route:
app.post("/eveniment/:id", function(req, res){ res.send("post route"); }
And I always get the error:
Cannot POST /eveniment/5f1740204a5a2206cc02b5af/eveniment/5f1740204a5a2206cc02b5af
It looks like somehow it doubles the route.
Just add a / at action="eveniment/<%=eveniment._id%>"
<form action="/eveniment/<%=eveniment._id%>" method="POST" id="modificaeveniment">
<input type="text" placeholder="titlu eveniment" name="titlu" value="<%= eveniment.name %>">
<button class="btn btn-info">Submit</button>
</form>```

Why CSRF is not working in only POST route While working in the rest of other Post routes?

I am getting the CSRF forbidden error. However CSRF is working fine in the rest of the application like post route of logout, signUp, Signin deleteing anything et c..
But when I perform the post action in only one route `/addProduct" I am getting the error Note that I am generating my CSRF token before routes declaration.
I am attaching the main file code and the front end code of addProduct.
Here is my main file code where I am generating token and including it in all routes
app.use(csrfProtection);
app.use(flash());
// USed to include token and isLoggedIn information to render in every page
app.use((req, res, next) => {
res.locals.isLoggedIn = req.session.isLoggedIn;
res.locals.csrfToken = req.csrfToken();
res.locals.user= req.session.user;
next();
});
// app.use((req, res, next) => {
// // throw new Error('Sync Dummy');
// if (!req.session.user) {
// return next();
// }});
app.use(multer({ storage: fileStorage,fileFilter:fileFilter }).single('image'));
app.use(shopRoute);
app.use(authRoute);
app.use('/admin',adminRoute);
app.use(errorController.get404);
This is the front end code for ADD_Product.ejs. Here I am including hidden input as well... to get CSRF value back to check it...
<form action="<%=path%>" enctype="multipart/form-data" method="POST">
<div class="form-group">
<label for="title">Title</label>
<input type="text" class="form-control" id="title" name="title" value="<%=product.title%>" >
</div>
<div class="form-group">
<label for="price">Price</label>
<input type="text" class="form-control" id="price" name="price" value="<%=product.price%>">
</div>
<div class="form-group">
<input type="file" class="form-control-file" id="exampleFormControlFile1" name="image" value="<%=product.imageUrl%>">
</div>
<div class="form-group">
<label for="exampleFormControlTextarea1">Description</label>
<textarea class="form-control" id="exampleFormControlTextarea1" rows="3" name="description" value="<%=product.description%>"></textarea>
</div>
<% if (path=="/admin/edit") { %>
<input type="hidden" name="productId" value="<%=product._id%>">
<% } %>
<input type="hidden" name="_csrf" value="<%= csrfToken %>">
<button type="submit" class="btn btn-primary btn-lg center">+ </button>
</form>

why am i getting forbidden error in only one post Route?

i am getting the CSRF forbidden error .
However csrf is working fine in the rest of the application like post route of logout,signUp,Signin deleteing anything e.t.c/.
But when i perform the post action in only one route "/addProduct"
i got the error
Note that i am generating my CSRF token before routes declaration.
I am attaching the main file code and the front end code of addProduct.
here is my main file code where i am generating token and including it in all routes
app.use(csrfProtection);
app.use(flash());
// USed to include token and isLoggedIn information to render in every page
app.use((req, res, next) => {
res.locals.isLoggedIn = req.session.isLoggedIn;
res.locals.csrfToken = req.csrfToken();
res.locals.user= req.session.user;
next();
});
// app.use((req, res, next) => {
// // throw new Error('Sync Dummy');
// if (!req.session.user) {
// return next();
// }});
app.use(multer({ storage: fileStorage,fileFilter:fileFilter }).single('image'));
app.use(shopRoute);
app.use(authRoute);
app.use('/admin',adminRoute);
app.use(errorController.get404);
This is the front end code for ADD_Product.ejs
here i am including hidden input as well...
to get csrf value back to check it...
<form action="<%=path%>" enctype="multipart/form-data" method="POST">
<div class="form-group">
<label for="title">Title</label>
<input type="text" class="form-control" id="title" name="title" value="<%=product.title%>" >
</div>
<div class="form-group">
<label for="price">Price</label>
<input type="text" class="form-control" id="price" name="price" value="<%=product.price%>">
</div>
<div class="form-group">
<input type="file" class="form-control-file" id="exampleFormControlFile1" name="image" value="<%=product.imageUrl%>">
</div>
<div class="form-group">
<label for="exampleFormControlTextarea1">Description</label>
<textarea class="form-control" id="exampleFormControlTextarea1" rows="3" name="description" value="<%=product.description%>"></textarea>
</div>
<% if (path=="/admin/edit") { %>
<input type="hidden" name="productId" value="<%=product._id%>">
<% } %>
<input type="hidden" name="_csrf" value="<%= csrfToken %>">
<button type="submit" class="btn btn-primary btn-lg center">+ </button>

req.body returns empty object on put request

Im trying to update data by using put request
im using method-override package and multer for file upload
im not able to figure out what is causing the problem because
my post route is working fine where objects are getting stored in database from req.body fields and file is getting uploaded
this is my route:
app.put("/browse/:id", function(req, res){
console.log( req.body); // returns empty object
console.log( req.file); //undefined
})
this is the form
<form action="/browse/<%= book._id %>?_method=PUT" enctype="multipart/form-data" method="POST">
<input value="<%= book.image %>" type="file" name="image" >
<input value="<%= book.title %>" type="text" name="title" required>
<textarea name="desc">
<%= book.description %>
</textarea>
<button class="btn btn-success" type="submit"> Update </button>
</form>
Sorry, i guess just forgot to put the upload.single('image') method in there. That solved it for me.

Resources