Error: Can't set headers after they are sent. authentication system - javascript

I want to write a little authentication app with mysql connection and I get this error all the time, but I need it this way.
I want to send a response if the client gets /admin if he is not an admin and if he is, admin should be rendered.
app.js
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var index = require('./routes/index');
const admin = require("./routes/admin");
const session = require("express-session");
var app = express();
app.set("trust proxy", 1);
app.use(session({
secret: "asdf",
resave: false,
cookie: {
maxAge: 120000
},
saveUninitialized: false
}));
function checkIfLoggedin(req,res,next){
if(!(req.originalUrl === "/") && !req.session.loggedIn){
res.redirect('/');
return;
}
next();
};
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use(checkIfLoggedin);
app.use('/', index);
app.use("/admin", admin);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
module.exports = app;
index.js
var express = require('express');
var router = express.Router();
const bcrypt = require('bcrypt-nodejs');
var dbPassword;
import mysql from "mysql";
//
/* GET home page. */
router.get('/', function(req, res, next) {
res.render('index', {});
});
router.post('/', function(req,res,next) {
console.log("1");
const enteredUsername = req.body.username;
const enteredPassword = req.body.password;
const con = mysql.createConnection({
host: "localhost",
user: "user",
password: "pass",
database: "db"
});
con.query('SELECT * FROM users WHERE username = ?;', [`${enteredUsername}`], (error, results, fields) => {
if (results.length > 0) {
console.log("2");
console.log(error);
let dbPassword = results[0].password;
bcrypt.compare(enteredPassword, dbPassword, (err,response) => {
console.log(err);
console.log(response);
console.log("3");
if (response == true) {
req.session.user = {
userId: results[0].userId,
username: results[0].username,
isAdmin: results[0].isAdmin,
};
req.session.loggedIn = true;
console.log("file");
if (req.session.user.isAdmin) {
res.redirect("/admin");
}
else{
res.redirect("/file/" + req.session.user.userId);
}
}
else{
req.session.loggedIn = false;
console.log("false");
res.send("Wrong password");
}
});
}
else{
res.send("Wrong Data");
}
});
});
module.exports = router;
admin.js
var express = require('express');
var router = express.Router();
/* GET users listing. */
router.get('/', function(req, res, next) {
if (!req.session.user.isAdmin) {
res.send("Du bist kein Admin!");
}
res.render("admin");
});
module.exports = router;
index.ejs
<!DOCTYPE html>
<html>
<head>
<title>Costufi</title>
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<link type="text/css" rel="stylesheet" href="stylesheets/materialize.min.css" media="screen,projection"/>
</head>
<body>
<main>
<center>
<div class="container">
<div class="z-depth-2" style="display: inline-block; padding: 20px 50px 10px 50px; margin-top: 15%;">
<form class="col s12" action="/" method="post">
<div class="row">
<h4>Login</h4>
<div class="input-field col s12">
<input type="text" name="username" id="username" class="validate">
<label for="username">Username</label>
</div>
</div>
<div class="row">
<div class="input-field col s12">
<input type="password" name="password" id="password" class="validate">
<label for="password">PassworD</label>
</div>
</div>
<div class="row">
<button class="left btn waves-effect waves-light indigo darken-2" type="submit" name="send">Login
<i class="material-icons right">send</i>
</div>
</form>
</div>
</div>
</center>
</main>
<script type="text/javascript" src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<script type="text/javascript" src="js/materialize.min.js"></script>
</body>
</html>

This error is caused when you attempt to send more than one response to the same request. I didn't study all the places in your code, but here's one obvious case:
/* GET users listing. */
router.get('/', function(req, res, next) {
if (!req.session.user.isAdmin) {
res.send("Du bist kein Admin!");
}
res.render("admin");
});
If your if test is true, then you end up doing both a res.send() and a res.render(). The res.render() triggers the warning because you've already sent a response on this connection and can't send another one. You should change it to this:
/* GET users listing. */
router.get('/', function(req, res, next) {
if (!req.session.user.isAdmin) {
res.send("Du bist kein Admin!");
} else {
res.render("admin");
}
});

Related

Cannot POST /login - POST http://localhost:3000/login 404 (Not Found)

I'm serving my login form but for some reason can't POST to login and actually log in. I think it has something to do with my route folders, but I've tried several iterations of the routing and can't seem to figure it out. I keep receiving error POST http://localhost:3000/login 404 (Not Found).
My app runs on port 3000.
CRUD path: "Routes" folder-> artists.js
const express = require('express');
const router = express.Router();
const passport = require('passport');
const Artist = require('../models/artist');
const catchAsync = require('../utils/catchAsync');
const ExpressError = require('../utils/ExpressError');
/* lists artists from database */
router.get('/', async (req, res) => {
const artists = await Artist.find({});
res.render('artists/index', { artists })
});
router.get('/new', (req, res) => {
res.render('artists/new');
});
router.get('/login', (req, res) => {
res.render('artists/login');
})
/* shows specific artists that exist in database */
/* link - show.ejs */
router.get('/:id', catchAsync(async(req, res,) => {
const artist = await Artist.findById(req.params.id);
if (!artist) {
req.flash('error', 'Cannot find that Artist');
return res.redirect('/artists');
}
res.render('artists/show', { artist });
}));
/* artist edits form*/
router.get('/:id/edit', catchAsync(async (req, res) => {
const artist = await Artist.findById(req.params.id);
if (!artist) {
req.flash('error', 'Cannot find that Artist');
return res.redirect('/artists');
}
res.render('artists/edit', { artist });
}))
router.put('/:id', catchAsync(async (req, res) => {
const { id } = req.params;
const artist = await Artist.findByIdAndUpdate(id, { ...req.body.artist });
res.redirect(`/artists/${artist._id}`);
}))
/* creating a new artist */
router.post('/new', catchAsync(async(req, res) => {
try {
const { email, username, password, location, genre, about, size } = req.body;
const artist = new Artist({ email, username, location, genre, about, size });
const registeredArtist = await Artist.register(artist, password);
req.flash('success', 'Successfully signed up!');
res.redirect(`/artists/${artist._id}`)
} catch (e) {
req.flash('error', 'Sorry, an artist with that email already exists');
res.redirect('/artists');
}
}));
/** Where I'm encountering my error **/
router.post('/login', passport.authenticate('local', { failureFlash: true, failureRedirect: '/login' }), (req, res) =>{
req.flash('success', 'Welcome back!');
res.redirect('/artists');
})
/* delete a post */
router.delete('/:id', catchAsync(async (req, res) => {
const{ id } = req.params;
await Artist.findByIdAndDelete(id);
res.redirect('/artists');
}))
router.all('*', (req, res, next) => {
next(new ExpressError('Page Not Found', 404))
})
router.use((err, req, res, next) => {
const { statusCode = 500, message = 'Something went wrong' } = err;
res.status(statusCode).render('error');
})
module.exports = router;
Here's the ejs form w/ path: "Views" folder-> "artists" folder-> login.ejs
<% layout('layouts/boilerplate')%>
<div class="container d-flex justify-content-center align-items-center mt-5">
<div class="row">
<div class="col-md-6 offset-md-3 col-xl-4 offset-xl-4">
<div class="card shadow">
<img src="https://images.unsplash.com/photo-1571863533956-01c88e79957e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1267&q=80"
alt="" class="card-img-top" />
<div class="card-body">
<h5 class="card-title">Login</h5>
<form action="/login" method="POST" class="validated-form" novalidate>
<div class="mb-3">
<label class="form-label" for="artist[username]">Username</label>
<input class="form-control" type="text" id="artist[username]" name="artist[username]" required autofocus>
<div class="valid-feedback">
Looks good!
</div>
</div>
<div class="mb-3">
<label class="form-label" for="artist[password]">Password</label>
<input class="form-control" type="password" id="artist[password]" name="artist[password]" required>
<div class="valid-feedback">
Looks good!
</div>
</div>
<button class="btn btn-success btn-block">Login</button>
</form>
</div>
</div>
</div>
</div>
</div>
Below is my app.js to display all routes. I also have "users" and "events". Only Users and Artists can login.
const express = require('express');
const path = require('path');
const mongoose = require('mongoose');
const ejsMate = require('ejs-mate');
const catchAsync = require('./utils/catchAsync');
const methodOverride = require('method-override');
const passport = require('passport');
const LocalStrategy = require('passport-local');
const session = require('express-session');
const Artist = require('./models/artist');
const Event = require('./models/event');
const User = require('./models/user');
const flash = require('connect-flash');
const eventRoutes = require('./routes/events');
const userRoutes = require('./routes/users');
const artistRoutes = require('./routes/artists');
const dbUrl = process.env.DB_URL || 'mongodb://localhost:27017/macro-tickets';
mongoose.connect(dbUrl, {
useNewUrlParser: true,
useCreateIndex: true,
useUnifiedTopology: true,
useFindAndModify: false
});
const db = mongoose.connection;
db.on("error", console.error.bind(console, "connection error:"));
db.once("open", () => {
console.log("Database connected");
});
const app = express();
app.engine('ejs', ejsMate);
app.set('view engine', 'ejs');
app.set('views', path.join(__dirname, 'views'))
/* method override allows to serve put requests into the database */
app.use(express.urlencoded({ extended: true }));
app.use(methodOverride('_method'));
app.use(express.static(path.join(__dirname, 'public')))
const sessionConfig = {
secret: 'thisshouldbeabettersecret!',
resave: false,
saveUninitialized: true,
cookie: {
httpOnly: true,
expires: Date.now() + 1000 * 60 * 60 * 24 * 7,
maxAge: 1000 * 60 * 60 * 24 * 7
}
}
app.use(session(sessionConfig))
app.use(flash());
app.use((req, res, next) => {
res.locals.success = req.flash('success');
res.locals.error = req.flash('error');
next();
})
app.use(passport.initialize());
app.use(passport.session());
passport.use(new LocalStrategy(User.authenticate()));
passport.use(new LocalStrategy(Artist.authenticate()));
passport.serializeUser(User.serializeUser());
passport.serializeUser(Artist.serializeUser());
passport.deserializeUser(User.deserializeUser());
passport.deserializeUser(Artist.deserializeUser());
app.use('/events', eventRoutes)
app.use('/users', userRoutes);
app.use('/artists', artistRoutes)
app.listen(3000, () => {
console.log('Serving on port 3000')
})
The form is POSTing to '/login' but nothing is going through. Any ideas what I'm doing wrong?
If to use this router you are calling it with
app.use("/your-route", require("../routes/artists.js")
the correct address would be http://localhost:3000/your-route/login.
In your case it seems I can think what you do:
app.use("/artists", require("../routes/artists.js")
then the post request would be http://localhost:3000/artists/login.
You can try this,
Update this in your app.js file
app.use(require('./routes/artists'))
then your request link will be like http://localhost:3000/login

Express.js routers post request returns 404

My express server returns 404 error when i try to send request from html form. However get request works fine. I have separated files for server and routes. I can't make requests in app.js, because there are too many of them (for different pages). I want to make post-insert request to db, but i just can't get any information from my form.
Is there something i missing?
my html form (ejs precisely)
<form action="/add" method="POST">
<input type="text" name="title" placeholder="Event name" />
<input type="text" name="subcategory" placeholder="Category" />
<input type="text" name="date" placeholder="Date" />
<input type="text" name="place" placeholder="Place" />
<input type="text" name="organisator" placeholder="Organisator" />
<textarea name="description" placeholder="Description" onkeyup="adjust_textarea(this)"></textarea>
<input type="submit" value="Add" />
</form>
my App.js file (error on 404 handler)
const express = require('express');
const path = require('path');
const logger = require('morgan');
const cookieParser = require('cookie-parser');
const bodyParser = require('body-parser');
var app = express();
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
//db connection
var mysql = require("mysql");
app.use(function(req, res, next){
res.locals.connection = mysql.createConnection({
host : 'localhost',
user : 'root',
password : 'mypassword',
database : 'mydb'
});
res.locals.connection.connect();
next();
});
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', require('./routes/index'));
app.use('/events', require('./routes/events'));
//handling errors
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
app.use(function(err, req, res, next) {
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
res.status(err.status || 500);
res.render('error');
});
//server init
var http = require('http');
var server = http.createServer(app);
server.listen(4000);
if(server.listening){
console.log('Server is listening on port 4000');
}
module.exports = app;
my ./routes/events.js file
const express = require('express');
const router = express.Router();
router.get('/', function (req, res, next) {
let query = '*select query*';
res.locals.connection.query(query, function (error, results, fields) {
if (error) throw error;
res.render('index', { title: 'Events', data: results });
});
});
router.post('/add', function (req, res) {
var obj = req.body.title;
console.log(obj);
res.redirect('/events');
});
What i see in browser
You have the 'add' endpoint listed in in your 'routes/events.js' file, which causes the structure of the final route to be '/events/add.' In your form, you are sending to the '/add' endpoint so to fix the issue, either change the action prop on the form to '/events/add' or move the '/add' endpoint into it's own route like this:
router.post('/add', function(req, res) {
var obj = req.body.title;
console.log(obj);
res.redirect('/events');
});

Unable to determine error messages while implementing passport.js local-signup

I'm adapting this local authentication implementation (using Sequelize instead of Mongoose, but this should be DB agnostic), and here is my following directory hierarchy:
app.js
package.json
node_modules
config
-----env
-----config.js
-----passport.js
-----sequelize.js
views
-----index.ejs
-----login.ejs
-----signup.ejs
I have the routes defined in app.js and the models defined in sequelize.js, as described below:
./app.js
const express = require('express');
const http = require('http');
const https = require('https');
const sequelize = require('sequelize');
const db = require('./config/sequelize');
const config = require('./config/config');
const passport = require('passport');
const strategies = require('./config/passport')(passport);
const env = 'development';
const app = express();
const port = 3000;
app.set('view engine', 'ejs');
app.use(passport.initialize());
app.use(passport.session());
app.listen(port);
function isLoggedIn(req, res, next) {
if (req.isAuthenticated()){
return next();
}
else{
res.redirect('/');
}
}
app.post('/signup', function(req, res){
console.log("nothing");
passport.authenticate('local-signup', {
successRedirect : '/profile',
failureRedirect : '/signup',
failureFlash : false // allow flash messages
}
}));
./config/passport.js
const LocalStrategy = require('passport-local').Strategy;
const passport = require('passport');
const User = require('../config/sequelize');
module.exports = function(passport) {
passport.serializeUser(function(user, done) {
console.log("Serializing user");
done(null, user.id);
});
passport.deserializeUser(function(id, done) {
console.log("Deserializing user");
User.findById(id, function(err, user) {
done(err, user);
});
});
passport.use('local-signup', new LocalStrategy({
usernameField : 'email',
passwordField : 'password',
passReqToCallback : true
},
function(req, email, password, done) {
console.log("Inside local strategy");
process.nextTick(function() {
User.findOne({ 'local.email' : email }, function(err, user){
if (err){
console.log("nothing");
return done(err);
}
if (user) {
console.log("There is already a user attached to this email.");
return done(null);
}
else {
const newUser = new User();
newUser.local.email = email;
newUser.local.password = password;
newUser.save(function(err) {
if (err)
throw err;
return done(null, newUser);
});
}
});
});
}));
};
./views/signup.ejs
<!doctype html>
<html>
<head>
<title>Node Authentication</title>
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.2/css/bootstrap.min.css">
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.min.css"> <!-- load fontawesome -->
<style> body { padding-top:80px; }</style>
</head>
<body>
<div class="container">
<div class="col-sm-6 col-sm-offset-3">
<h1><span class="fa fa-sign-in"></span> Signup</h1>
<% if (message.length > 0) { %>
<div class="alert alert-danger"><%= message %></div>
<% } %>
<form action="/signup" method="post">
<div class="form-group">
<label>Email</label>
<input type="text" class="form-control" name="email">
</div>
<div class="form-group">
<label>Password</label>
<input type="password" class="form-control" name="password">
</div>
<button type="submit" class="btn btn-warning btn-lg">Signup</button>
</form>
<hr>
<p>Already have an account? Login</p>
<p>Or go home.</p>
</div>
</div>
</body>
</html>
And for good measure:
./config/sequelize.js
const path = require('path');
const Sequelize = require('sequelize');
const _ = require('lodash');
const config = require('./config');
const db = {};
const sequelize = new Sequelize(config.db.name, config.db.username, config.db.password, {
host: config.db.host,
port: config.db.port,
dialect: 'mysql',
storage: config.db.storage
});
sequelize
.authenticate()
.then(function(err) {
console.log('Connection has been established successfully.');
}, function (err) {
console.log('Unable to connect to the database:', err);
});
const User = sequelize.define('User', {
username: Sequelize.STRING,
email: Sequelize.STRING,
password: Sequelize.STRING
});
sequelize.sync();
module.exports = User;
What occurs when I run the app and press the signup button
is the "nothing" console.log statement in config/passport.js, but when I try to diagnose the source of the error by adding console.log statements on 'err' nothing appears to show up on cmd.

NodeJS express Post form - action always 404

No matter what link I declare in the action of my form, it always returns an 404 error. if I change the method to get, it doesn't.
I want to use post because i'm trying to get the data from my input fields and post it in my mongedb database:
HTML:
<form class="container-fluid searchContainer" action="/active" method="post">
<div class="col-xs-6">
<div class="form-group">
<label for="businessUnit">Business unit</label>
<input type="text" ng-model="businessUnit" id="businessUnit" name="businessUnit" class="form-control"/>
</div>
<div class="form-group">
<label for="tenderId">Tender ID</label>
<input type="text" name="tenderID" ng-model="tenderId" id="tenderId" class="form-control"/>
</div>
</div>
<div class="col-xs-6">
<div class="form-group">
<label for="tenderDate">Tender Bidding Date</label>
<input type="date" ng-model="tenderDate" name="tenderDate" id="tenderDate" class="form-control"/>
</div>
<div class="form-group">
<label for="therapyArea">Therapy area</label>
<input type="text" ng-model="therapyArea" name="therapyArea" id="therapyArea" class="form-control"/>
</div>
</div>
<div class="col-md-12 text-right">
<input type="submit" id="btnCreate" value="Create" class="btn btn-primary" >
</div>
</form>
JAVASCRIPT:
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var routes = require('./routes/index');
var users = require('./routes/users');
var active = require('./routes/active');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
extended: true
}));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', routes);
app.use('/users', users);
app.use('/active', active);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
// error handlers
// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: err
});
});
}
// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: {}
});
});
module.exports = app;
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/tenders');
var db = mongoose.connection;
db.on('error', function(err) {
console.log('connection error', err);
});
db.once('open', function() {
console.log('connected.');
});
var Schema = new mongoose.Schema({
TenderID: String,
TenderDate: String,
BusinessUnit: String,
TherapyUnit: String
});
var Tender = mongoose.model('Tender', Schema);
app.post('/active', function(req, res) {
new Tender({
TenderID: req.body.tenderID,
TenderDate: req.body.tenderDate,
BusinessUnit: req.body.businessunit,
TherapyUnit: req.body.therapyUnit
}).save(function(err, doc) {
if (err) res.json(err);
else res.send('Succesfully insterted')
})
});
Because you define your 404 route handler before you define app.post('/active'), express evaluates the 404 rule first and returns it. Your POST /active route never gets evaluated. To fix this you need to give Express your POST /active route before your 404 route (which should always be your last route).
Unless you have an equivalent POST /active route defined in the file ./routes/active, the line
app.use('/active', active);
won't fix this problem even though it is evaluated before your 404 route. You can read more about app.use() vs app.get|post|etc() in the express docs.
Express evaluates rules in the order they are passed to it via use() or get|post|delete|etc()
You have defined get route in your server. Try to change the
app.get('/active',function(req,res){
into
app.post('/active',function(req,res){
In this way, you will respond to a post request from the browser.

Req.flash(errors) Not Displaying -NodeJS 5.7.0

I am trying to make it so when a user enters an email that is already in the db to let the user know that that account email is already registered.
I am getting the correct error from mongo db but I dont want to display all that junk. I want it to just display my error on my signup page in the form saying something like "This email address is registered already".
MongoDB Response:
MongoError: E11000 duplicate key error index: jcommerce.users.$email_1 dup key: { : "james12345#gmail.com" }
at Function.MongoError.create (C:\jcommerce\node_modules\mongodb-core\lib\error.js:31:11)
at toError (C:\jcommerce\node_modules\mongodb\lib\utils.js:114:22)
at C:\jcommerce\node_modules\mongodb\lib\collection.js:616:23
at handleCallback (C:\jcommerce\node_modules\mongodb\lib\utils.js:96:12)
at C:\jcommerce\node_modules\mongodb\lib\bulk\unordered.js:470:9
at handleCallback (C:\jcommerce\node_modules\mongodb\lib\utils.js:96:12)
at resultHandler (C:\jcommerce\node_modules\mongodb\lib\bulk\unordered.js:417:5)
at commandCallback (C:\jcommerce\node_modules\mongodb-core\lib\topologies\server.js:936:9)
at Callbacks.emit (C:\jcommerce\node_modules\mongodb-core\lib\topologies\server.js:116:3)
at null.messageHandler (C:\jcommerce\node_modules\mongodb-core\lib\topologies\server.js:282:23)
at Socket.<anonymous> (C:\jcommerce\node_modules\mongodb-core\lib\connection\connection.js:273:22)
at emitOne (events.js:90:13)
at Socket.emit (events.js:182:7)
at readableAddChunk (_stream_readable.js:153:18)
at Socket.Readable.push (_stream_readable.js:111:10)
at TCP.onread (net.js:529:20)
Route Class
var router = require('express').Router();
var User = require('../models/user')
router.get('/signup', function (req, res, next) {
res.render('accounts/signup', {
errors: req.flash('errors')
});
});
router.post('/signup', function(req, res, next) {
var user = new User();
user.profile.name = req.body.name;
user.email = req.body.email;
user.password = req.body.password;
// Validate
User.findOne({email: req.body.email}, function (err, existingUser) {
if (existingUser) {
req.flash('errors', 'Account with that email address already exists');
return res.redirect('/signup');
}
else {
// save user to database
user.save(function(err, user) {
if (err) {
return next(err);
}
return res.redirect('/');
});
}
}); // Mongoose method find one document in db
});
module.exports = router;
EJS
<% layout('layout') -%>
<div class="row">
<div class="col-lg-6 col-md-offset-3">
<% if (errors.length > 0) { %>
<div class="alert alert-danger alert-dismissible">
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
<%= errors %>
</div>
<% } %>
<form method="post">
<h1> Signup! </h1>
<div class="form-group">
<label="name"> Name: </label>
<input type="text" class="form-control" name="name">
</div>
<div class="form-group">
<label="name"> Email: </label>
<input type="email" class="form-control" name="email">
</div>
<div class="form-group">
<label="name"> Password: </label>
<input type="passwod" class="form-control" name="password">
</div>
<button type="submit" class="btn btn-success"> Submit</button>
</form>
</div>
</div>
Server.js AKA app.js
// Require library we want to use
var express = require('express');
var morgan = require('morgan');
var mongoose = require('mongoose');
var bodyParser = require('body-parser');
var ejs = require('ejs');
var engine = require('ejs-mate');
var session = require('express-session');
var cookieParser = require('cookie-parser'); // parses cookies and put it on the request object in the middleware
var flash = require('express-flash');
var User = require('./models/user');
// App is reffering to express objects, bc we want to use express objects
var app = express();
mongoose.connect('mongodbconnectionstring', function (err) {
if (err) {
console.log(err);
}
else
{
console.log("Connected to the database");
}
});
//Middleware - logs requests in cmd
app.use(express.static(__dirname + '/public'));
app.use(morgan('dev'));
app.use(bodyParser.json()); // Express can parse data format
app.use(bodyParser.urlencoded({extended: true}));
app.use(cookieParser());
app.use(session({
resave: true,
saveUninitialized: true,
secret: "James#####"
}));
app.use(flash());
app.engine('ejs', engine)
app.set('view engine', 'ejs');
// body parser takes the body of request and parses it -> Format encoded or raw data
var mainRoutes = require('./routes/main');
var userRoutes = require('./routes/user');
app.use(mainRoutes); // Express is using main routes
app.use(userRoutes);
// Listen on port number 3000 ,
app.listen(3000, function (err) {
if (err) {
throw err;
}
console.log("Server is Running on port 3000");
});
The error stems from this line:
user.email = req.body.email;
This occurs because req.body.email is undefined which means the email is not unique. You should verify that the request to /signup is sent with data from the client.
I just had to check if
exisitinguser !== null
if (existingUser !== null)

Categories