Mail not sent by node mailer - node.js

I am trying to send mail when we click the mail icon of respective id. But I am not able to send the mail.
First I click the icon, it redirects to another ejs file for sending email and then the email is sent from there. Here the mail is not sent so can anyone please help?
Thank you
mail.ejs
<form action="/send-email" method="POST">
<div class="col-md-12">
<div class="form-group">
<input type="text" class="form-control" placeholder="To" name="to">
</div>
<div class="form-group">
<input type="text" class="form-control" placeholder="From" name="from" id="from">
</div>
<div class="form-group">
<input type="text" class="form-control" placeholder="Subject" name="subject" id="subject">
</div>
<div class="form-group">
<textarea class="form-control" id="content" rows="4"></textarea>
</div>
<button type="submit" class="btn btn-primary" id="">Send</button>
</div>
</form>
Controller.js
router.get('/donation/mail/:emailid', function (req, res, next) {
res.render('mail', {email: req.query.emailid});
})
router.post('/send-email', function (req, res) {
var transport = nodemailer.createTransport(smtpTransport({
service: "gmail",
port:425,
auth: {
// should be replaced with real sender's account
user: 'xxxx#gmail.com',
pass: 'gmailpassword'
}
}));
var mailOptions = {
// should be replaced with real recipient's account
from:'xxxxx#gmail.com',
to : req.param.email,
subject : req.body.subject,
text : req.body.text
};
transport.sendMail(mailOptions, function(error, info) {
if (error) {
return console.log(error);
}
console.log('Message sent: ' + info.response);
});
res.redirect("/donation");
});
I have allowed my gmail account to access non secure app

Related

node.js POST empty req.body

I'm having trouble when I store data to MySQL database. I get a return in console blank.like this {}
here's route code :::app.post('/create', employeeController.create);
this is my controller code
exports.create = function(req, res) {
console.log((req.body));
const new_employee = new Employee(req.body);
//handles null error
if(req.body.constructor === Object && Object.keys(req.body).length === 0){
res.status(400).send({ error:true, message: 'Please provide all required field' });
}else{
Employee.create(new_employee, function(err, employee) {
if (err)
res.send(err);
res.json({error:false,message:"Employee added successfully!",data:employee});
});
}
};
this is my model code:
var db = require('../database');
//Employee object create
var Employee = function(employee){
this.name = employee.name;
this.email = employee.email;
this.position = employee.position;
};
Employee.create = function (newEmp, result) {
db.query("INSERT INTO employee set ?", newEmp, function (err, res) {
if(err) {
console.log("error: ", err);
result(err, null);
}
else{
console.log(res.insertId);
result(null, res.insertId);
}
});
};
module.exports= Employee;
my view code:
<form action="/create" enctype="multipart/form-data" method="POST">
<div class="row">
<div class="col-md-6">
<label>Name</label>
<input name="name" type="text" class="form-control" required>
</div>
<div class="col-md-6">
<label>Email</label>
<input name="email" type="email" class="form-control" required>
</div>
</div>
<div class="row">
<div class="col-md-6">
<label for="exampleFormControlTextarea1" class="form-label">Position</label>
<input name="position" type="text" class="form-control" required>
</div>
</div>
<button type="submit" class="btn btn-primary">Save</button>
<button type="submit" class="btn btn-primary">Cancel</button>
<br><br>
</form>
Im getting {} in log it means req.body is getting blank.
i have tried in app.js
app.use(bodyParser.json());
app.use(express.urlencoded({limit: '100mb',extended: false }));
but it's not working
Add app.use(bodyParser.urlencoded({ extended: false })) before your app.use(bodyParser.json());, and remove app.use(express.urlencoded({limit: '100mb',extended: false }));.
app.use(bodyParser.urlencoded({ extended: false }))
app.use(bodyParser.json());
Then remove enctype="multipart/form-data" in the form. Because your form only have text input, so you could remove it. And bodyParser doesn't support multipart/form-data.

Nothing happening after hitting submit button on form

Nothing is happening after hitting the submit button on my form. Not an error nothing happens. I'm using node.js with express and nodemailer to submit my form. Most of the questions related to this are php and aren't in this area. Any help you give would be greatly appreciated.
Here's my server.js:
app.post('/contact', function (req, res) {
//Check if all required fields are filled
if (!req.body.name || !req.body.email || !req.body.message) {
res.render('contact', {
title: 'Contact',
err: true,
page: 'contact',
type: 'empty',
body: req.body.message,
name: req.body.name,
email: req.body.email,
msg: 'Thanks.',
description: 'Email is successful'
});
return;
}
//Set up smtp mailer
smtpTrans = nodemailer.createTransport({
service: 'Gmail',
auth: {
user: "madeforgoggl#gmail.com",
pass: ""
}
});
//Fill mail options
mailOpts = {
from: req.body.name + '<' + req.body.email + '>', // grab form data from the requet body
to: 'madeforgoggle#gmail.com',
subject: 'Website contact',
text: req.body.message + ' || NAAM:' + req.body.name + ' || EMAIL:' + req.body.email
};
smtpTrans.sendMail(mailOpts, function (error, info) {
//Email not sent
if (error) {
//console.log(error)
res.render('contact', {
title: 'Contact',
page: 'contact',
type: 'error',
description: 'Email not successful'
});
}
// Yay!! Email sent
else {
res.render('contact', {
title: 'Contact',
page: 'contact',
type: 'success',
description: 'Email successful'
});
}
});
});
Here is my form- Changed the button action to a input submit because I thought that was the problem:
<form action="/contact" id="contact-form" method="post" role="form">
<div class="form-group">
<input id="yourname" type="text"name="name" placeholder="name" class="form-control" required size="40" />
</div>
<div class="form-group">
<input id="yourcompany" type="text" name="company" placeholder="company" class="form-control" required size="40" /> <
</div>
<div class="form-group">
<input id="youremail" type="email" name="email" placeholder="email" class="form-control" required size="40" /> <
</div>
<div class="form-group">
<textarea id="yourmessage" name="message" class="form-control" placeholder="MESSAGE" required size="40" rows="10"></textarea>
</div>
<div class="form-group">
<input type="submit" class="btn btn-block btn-danger">
Send Message
</input>
I've been working on this since 4 am and can't seem to figure out what is wrong. Any help is greatly appreciated.

Why am I getting a 400 bad request error when submitting a form that I added inputs to?

Background: I have a node/express based web application that is basically a rating/database site for campgrounds. You can view the current working version here: https://radiant-eyrie-76078.herokuapp.com and the github here: https://github.com/HashSlingSlash/YelpCamp. I've just completed attempting to add user profiles by updating the signup form to include more information and adding a show page for each user. Now whenever I click the signup button (or send a post request to /register using postman) I get a 400 Bad Request error. If I then go to the home page I can sign in as the user that I attempted to register so the user is getting registered despite the bad request error. I have tried clearing my cache and browsing history and using other browsers, but it still won't work. I even tried removing all the changes I made to the form to make it just username and password again and it still did not work. I have tried fixing this and debugging for hours and I cannot understand what could be happening.
Here is my register page:
<%- include("./partials/header") %>
<div class="row">
<h1 class="login-header">Sign Up</h1>
<div class="login-form">
<form action="/register" method="POST">
<div class="form-group">
<label for="username">Username</label>
<input class="form-control" type="text" name="newUser[username]" placeholder="username" id="username">
</div>
<div class="form-group">
<label for="password">Password</label>
<input class="form-control" type="password" name="password" placeholder="password" id="password">
</div>
<div class="form-group">
<label for="firstName">First Name</label>
<input class="form-control" type="text" name="newUser[firstName]" placeholder="First Name" id="firstName">
</div>
<div class="form-group">
<label for="lastName">Last Name</label>
<input class="form-control" type="text" name="newUser[lastName]" placeholder="Last Name" id="lastName">
</div>
<div class="form-group">
<label for="email">Email</label>
<input class="form-control" type="email" name="newUser[email]" placeholder="email#mail.com" id="email">
</div>
<div class="form-group">
<label for="avatar">Avatar</label>
<input class="form-control" type="text" name="newUser[avatar]" placeholder="avatar url" id="avatar">
</div>
<div class="form-group">
<label for="admin">Admin Key (Enter admin key here if you've been given one)</label>
<input class="form-control" type="text" name="adminKey" placeholder="********" id="admin">
</div>
<div class="form-group">
<button class="btn btn-lg btn-primary btn-block">Sign Up!</button>
</div>
</form>
Go Back
</div>
</div>
<%- include("./partials/footer") %>
Here are my index routes:
const express = require("express");
const router = express.Router();
const passport = require("passport");
const User = require("../models/user");
const Campground = require("../models/campground");
//root route
router.get("/", (req, res) =>{
res.render("landing");
});
//show register form
router.get("/register", (req, res) =>{
res.render("register", {page: "register"});
});
//handle sign up logic
router.post("/register", (req, res) =>{
const newUser = new User(req.body.newUser);
if(req.body.adminKey === "secret"){
newUser.isAdmin = true;
}
User.register(newUser, req.body.password, (err, user) =>{
if(err){
return res.render("register", {"error": err.message});
}
passport.authenticate("local")(req, res, () =>{
req.flash("success", "Welcome to YelpCamp " + user.username);
res.redirect("/campgrounds");
});
});
});
//login form
router.get("/login", (req, res) =>{
res.render("login", {page: "login"});
});
//login logic
router.post("/login",
passport.authenticate("local",
{
failureRedirect: "/login",
failureFlash: true
}), (req, res) =>{
req.flash("success", "Welcome back " + req.user.username);
res.redirect("/campgrounds");
});
//logout
router.get("/logout", (req, res) =>{
req.logOut();
req.flash("success", "Logged you out!");
res.redirect("/campgrounds");
});
//user profile
router.get("/user/:id", (req, res) =>{
User.findById(req.params.id, (err, foundUser) =>{
if(err){
req.flash("error", "Something went wrong");
return res.redirect("back");
}
Campground.find().where("author.id").equals(foundUser._id).exec((err, campgrounds) =>{
if(err){
req.flash("error", "Something went wrong");
return res.redirect("back");
}
res.render("users/show", {user: foundUser, campgrounds: campgrounds});
});
});
});
module.exports = router;
Here is my User schema:
const mongoose = require("mongoose");
const passportLocalMongoose = require("passport-local-mongoose");
const UserSchema = new mongoose.Schema({
username: String,
password: String,
firstName: String,
lastName: String,
email: String,
avatar: String,
isAdmin: {type: Boolean, default: false}
});
UserSchema.plugin(passportLocalMongoose);
module.exports = mongoose.model("User", UserSchema);
I've tried fixing this for hours and would appreciate any help!
I finally figured out the issue. I had to change the name attribute on the form inputs to just username, password, email, etc. I believe passport local mongoose expects to receive the data according to those key value pairs specifically, although I am unsure as to the exact reason why this is necessary since I end up giving the data as an object either way. In case anyone wants to see it here is my updated and working code:
Register form:
<%- include("./partials/header") %>
<div class="row">
<h1 class="login-header">Sign Up</h1>
<div class="login-form">
<form action="/register" method="POST">
<div class="form-group">
<label for="username">Username</label>
<input class="form-control" type="text" name="username" placeholder="username" id="username">
</div>
<div class="form-group">
<label for="password">Password</label>
<input class="form-control" type="password" name="password" placeholder="password" id="password">
</div>
<div class="form-group">
<label for="firstName">First Name</label>
<input class="form-control" type="text" name="firstName" placeholder="First Name" id="firstName">
</div>
<div class="form-group">
<label for="lastName">Last Name</label>
<input class="form-control" type="text" name="lastName" placeholder="Last Name" id="lastName">
</div>
<div class="form-group">
<label for="email">Email</label>
<input class="form-control" type="email" name="email" placeholder="email#mail.com" id="email">
</div>
<div class="form-group">
<label for="avatar">Avatar</label>
<input class="form-control" type="text" name="avatar" placeholder="avatar url" id="avatar">
</div>
<div class="form-group">
<label for="admin">Admin Key (Enter admin key here if you've been given one)</label>
<input class="form-control" type="text" name="adminKey" placeholder="********" id="admin">
</div>
<div class="form-group">
<button class="btn btn-lg btn-primary btn-block">Sign Up!</button>
</div>
</form>
Go Back
</div>
</div>
<%- include("./partials/footer") %>
Route:
//handle sign up logic
router.post("/register", (req, res) =>{
const newUser = new User({
username: req.body.username,
firstName: req.body.firstName,
lastName: req.body.lastName,
email: req.body.email,
avatar: req.body.avatar
});
if(req.body.adminKey === "secret"){
newUser.isAdmin = true;
}
User.register(newUser, req.body.password, (err, user) =>{
if(err){
return res.render("register", {"error": err.message});
}
passport.authenticate("local")(req, res, () =>{
req.flash("success", "Welcome to YelpCamp " + user.username);
res.redirect("/campgrounds");
});
});
});

Unable to update MongoDB from edit profile page

I am trying to update my particular user database on edit profile page.But I don't know where I am going wrong in it.
{{!--editProfile.hbs--}}
<link rel="stylesheet" href="myprofile.css">
<title>Edit Profile Page</title>
<body>
<div class="container">
<h1>Edit Profile</h1>
<hr>
<div class="row">
<!-- left column -->
<div class="col-md-3">
<div class="text-center">
<img src="//placehold.it/100" class="avatar img-circle" alt="avatar">
<h6>Upload a different photo...</h6>
<input type="file" class="form-control">
</div>
</div>
<!-- edit form column -->
<div class="col-md-9 personal-info">
<h3>Personal info:</h3>
<form class="form-horizontal" role="form" action="/addDB" method="POST">
<div class="form-group">
<label class="col-lg-3 control-label" for="username">Username:</label>
<div class="col-lg-8">
<input class="form-control " type="text" id="username" name="username"placeholder="Username">
</div>
</div>
<div class="form-group">
<label class="col-lg-3 control-label">Email:</label>
<div class="col-lg-8">
<input class="form-control " type="text" placeholder="Email" name="email">
</div>
</div>
<div class="form-group">
<label class="col-md-3 control-label">Password:</label>
<div class="col-md-8">
<input class="form-control " type="password" placeholder="Password"name="password">
</div>
</div>
<div class="form-group">
<label class="col-md-3 control-label" for="phone">Phone:</label>
<div class="col-md-8">
<input class="form-control " type="text" id="phone" placeholder="Phone"name="phone">
</div>
</div>
<div class="form-group">
<label class="col-md-3 control-label"></label>
<div class="col-md-8">
button class="btn btn-primary" type="submit">Save Changes</button>
</div>
</div>
</form>
</div>
</div>
</div>
<hr>
</body>
</html>
//index.js
var express=require('express');
var app=express();
var session=require('express-session');
var mongoClient=require("mongodb").MongoClient;
var db;
mongoClient.connect("mongodb://localhost:27017",function(err,client){
if (err) throw err;
db=client.db("myDBS");
});
app.use(
session({secret: "Express session secret"}));
app.use(express.urlencoded({ extended:false}));
app.set('view engine', 'hbs');
app.use(express.static(__dirname + '/public'));
app.get("/", function(req, res){
res.sendFile(__dirname + "/login.html");});
//For Inserting new User in DB
app.get('/addS',function(req,res){
res.render('addNewUsers');
});
app.post("/add",function(req,res){
db.collection("users").insert(req.body);
console.log("Insert successfully");
res.render("myprofile");
});
//for updating DB
app.post('/addDB', function(req, res, next) {
var data = {
username: req.body.username,
email: req.body.email,
password: req.body.password,
phone:req.body.phone
};
// var id = req.body.id;
mongoClient.connect("mongodb://localhost:27017", function(err, db) {
db.collection('users').updateOne({$set: data}, function(err, result) {
console.log('User updated');
db.close();
});
});
});
app.get("/edit",function(req,res){
res.render("editProfile");
});
app.get("/dmyprofile",function(req,res){
res.render(307,"/myprofile");
});
app.post("/myprofile",function(req,res){
db.collection("users").find().toArray(function(err,result){
if (err) throw err;
for(var i=0;i<result.length;i++){
if(req.body.email==result[i].email &&
req.body.password==result[i].password)
{
req.session.loggedIn=true;
}
}
res.redirect("/user");
});
});
app.get("/user",function(req,res){
if(req.session.loggedIn==true){
res.render("myprofile");
}else{
res.redirect("/");
}
});
app.get("/logout",function(req,res){
req.session.destroy();
res.redirect("/");
});
app.listen(3355,function(){
console.log("Listening on 3355");
});
when I am clicking on save changes it is showing me db.collection not a function. Though my insert route is working fine but update part is not working.
All other routes are working fine. But this update part is throwing error.
The problem here is the way you are connecting to MongoDB.
To have direct access to the collections after connecting to Mongo you must have the database name in the connection string, like in the code below:
mongoClient.connect("mongodb://localhost:27017/MyDBS", function(err, db) {
db.collection('users').updateOne({$set: data});
});
The other way to get access to the collections is connecting to Mongo and choosing the which database to use right after, like you did upper in your code:
mongoClient.connect("mongodb://localhost:27017",function(err,client){
if (err) throw err;
db=client.db("myDBS");
db.collection('users').updateOne({$set: data});
});

Updating a user record in Passport + MongoDB

I'm trying to update a user record in passport via a POST request. I've had a look at various tutorials and a previous answer to a similar question. I've implemented the following code:
var User = require("../models/user");
router.get("/settings/profile/:id", isLoggedIn, function(req,res){
res.render("profile/profilesettings", {
User: req.user
});
});
router.post("/settings/profile/:id", isLoggedIn, function(req,res){
User.update({_id: req.session.passport.user.id}, {
email: req.body.email,
imageUrl: req.body.imageUrl,
bio: req.body.bio
}, function (err){
console.log(err);
});
res.render("profile/profilesettings", {
User: req.user
});
})
This is the form that executes the update function.
<form class="form-horizontal" action="/settings/profile/<%= currentUser._id %>" method="POST">
<div class="form-group">
<label class="control-label col-sm-2" for="username">Username:</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="username" name="username" placeholder="username" value="<%= currentUser.username %>" disabled>
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2" for="email">Email:</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="email" name="email" placeholder="email" value="<%= currentUser.email %>">
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2" for="profileimage">Upload Image:</label>
<div class="col-sm-10">
<div class="input-group">
<span class="input-group-btn">
<span class="btn btn-default btn-file">
Browse.. <input type="file" id="profileimage">
</span>
</span>
<input type="text" class="form-control" id="profileimage" name="profileimage" placeholder="Profile Pic">
</div>
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2" for="bio">Bio:</label>
<div class="col-sm-10">
<textarea class="form-control" rows="5" id="bio" name="bio" placeholder="Tell us about yourself!"><%= currentUser.bio %></textarea>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button class="btn btn-lg btn-primary">Save Changes</button>
</div>
</div>
</form>
I also have the following isLoggedIn middleware:
function isLoggedIn(req, res, next) {
if (req.isAuthenticated()) {
return next();
}
res.redirect("/login");
}
The application runs, but when I click 'Save Changes' a null result is returned and nothing is updated.
It's because you response to request before your document gets updated. You should move your response(res.render(...) inside update callback:
User.update({_id: req.session.passport.user.id}, {
email: req.body.email,
imageUrl: req.body.imageUrl,
bio: req.body.bio
}, function (err){
if (err) console.log(err);
res.render("profile/profilesettings", {
User: req.user
});
});
1) req.user._id and req.session.passport.user both are same. You can use req.user._id instead.
2) Most of my passport applications doesn't have req.session.passport.user.id, while req.session.passport.user itself is an id.
3) Try nesting inside the callbacks
router.post("/settings/profile/:id", isLoggedIn, function(req, res, next){
User.update({ id: req.session.passport.user }, {
email: req.body.email,
imageUrl: req.body.imageUrl,
bio: req.body.bio
}, function(err, user) {
if (err) return next(err);
User.findById(req.user._id, function(err, user) {
if (err) return next(err);
return res.render('profile/profilesettings', {
user:user
});
});
});
});

Resources