Why my middleware is not checking if the email already exists? - node.js

I am authenticating people using passportJS. The problem I have recently realised is the fact that users are able to register for more than one account. I have created a middleware to check whether the email is already in use but somehow it is still passing the test.
var User = require('../models/users');
var authMethods = {};
authMethods.isInUse = function(req,res,next){
User.findOne({"email" : req.body.email}, (err,user) => {
if(user){
req.flash('error',"This mail is already in use.");
res.redirect('/register');
}else {
return next();
}
});
}
module.exports = authMethods;
In my authentication page I am calling the middleware inside the route to meet the condition.
router.post('/register',authMethods.isInUse ,multipart(),function(req, res) {
var image = fs.readFileSync(req.files.image.path);
var profilePic = {data : image, contentType : 'image/png'};
var user = new User({
username: req.body.username,
email: req.body.email,
password: req.body.password,
occupation: req.body.occupation,
phone: req.body.phone,
profilePic : profilePic,
firstName : req.body.firstName,
lastName : req.body.lastName
});
user.save(function(err) {
req.logIn(user, function(err) {
req.flash("success", "Welcome to the site " + user.username);
res.redirect('/flats');
});
});
});
I haven't been able to spot the faulty approach that's causing the problem.

If multipart() does what I think it does (parse the request data into req.body), then req.body will probably not be populated in your middleware because it's being called before the multipart middleware.
Try switching the middleware functions around:
router.post('/register', multipart(), authMethods.isInUse, function(req, res) {
...
});

Related

Postman .post request stalls, will not process. Why is this happening?

Here is my code--------
const express = require("express");
const router = express.Router();
const gravatar = require("gravatar");
// Load User model
const User = require("../../models/User");
// #route GET api/users/test
// #desc Tests users route
// #access Public
router.get("/test", (req, res) => res.json({ msg: "Users Works" }));
// #route GET api/users/register
// #desc Register user
// #access Public
router.post("/register", (req, res) => {
User.findOne({ email: req.body.email }).then(user => {
if (user) {
return res.status(400).json({ email: "email already exists" });
} else {
const avatar = gravatar.url(req.body.email, {
s: "200", // Size
r: "pg", // Rating
d: "mm" // Default
});
const newUser = new User({
name: req.body.name,
email: req.body.email,
avatar,
password: req.body.password
});
}
});
});
module.exports = router;
When I attempt a postman test for the .post(/register ... ) route it stalls loading for some minutes before giving me the error of --
"Could not get any response
There was an error connecting to http://localhost:5000/api/users/register.
Why this might have happened:
The server couldn't send a response:
Ensure that the backend is working properly
Self-signed SSL certificates are being blocked:
Fix this by turning off 'SSL certificate verification' in Settings > General
Proxy configured incorrectly
Ensure that proxy is configured correctly in Settings > Proxy
Request timeout:
Change request timeout in Settings > General"
Tweaking the suggested options did nothing and I'm lead to think neither of these things are the cause, as I am able to successfully process the .get(/test) route.
**point of note, I add the key:values in the body of the postman request for name, email and password. The avatar is generated from the email.
This is the route I use(post) --- http://localhost:5000/api/users/register
and for reference this is the working route (get)
--- http://localhost:5000/api/users/test
Any help would be great!
There is no return statement in the else block. Try as following... It should work
// #route GET api/users/register
// #desc Register user
// #access Public
router.post("/register", (req, res) => {
User.findOne({ email: req.body.email }).then(user => {
if (user) {
return res.status(400).json({ email: "email already exists" });
} else {
const avatar = gravatar.url(req.body.email, {
s: "200", // Size
r: "pg", // Rating
d: "mm" // Default
});
return res.status(200).json(new User({
name: req.body.name,
email: req.body.email,
avatar,
password: req.body.password
}));
}
});
});
I guess you are trying to register a user and save it mongoDB and return the response.
What you are doing wrong is you are not responding the data back to user. Also you are not saving anything in the whole API call..
Here's how you can do it.
router.post("/register", (req, res, next) => {
User.findOne({ email: req.body.email }).then(user => {
if (user) {
return res.status(400).json({ email: "email already exists" });
} else {
const avatar = gravatar.url(req.body.email, {
s: "200", // Size
r: "pg", // Rating
d: "mm" // Default
});
const newUser = new User({
name: req.body.name,
email: req.body.email,
avatar,
password: req.body.password
});
newUser.save()
.then(user => {
res.status(201).json(user); // 201 is HTTP Code for "Created"
});
.catch(next); // we usually handle error in a common middleware, which is why, I am calling "next" here with error as 1st argument.
}
});
});

Best way to validate uniqueness of a field Mangoose Node

When registering a new user, I want to check email for uniqueness. I am using body parser to make sure all fields are not empty, but how am I to check that the input email is not used by anyone else and to immediately output the message for a user?
The technology stack is Node.js, mongoose, body-parser module, mongodb
Here's the route file:
router.post('/register', function(req, res){
let name = req.body.name;
let email = req.body.email;
req.checkBody('name', 'Name field is empty!').notEmpty();
req.checkBody('email', 'Email field is empty!').notEmpty();
req.checkBody('email', 'Invalid email format').isEmail();
var errors = req.validationErrors();
if(errors){
res.render('register', {
errors:errors
});
} else {
let newUser = new User({
name: name,
email: email
});
After looking through similar questions, I found a way to use a pre save in my model file, but I don't know how to sisplay the error to the user as a part of the errors array (see above)
Any help will be highly appreciated!
You can achieve both from the Mongoose model and the Register() method.
The user model should be like this:
var mongoose = require('mongoose');
var UserSchema = new mongoose.Schema({
email: {
type: String,
lowercase: true,
unique: true,
sparse: true
},
password: {
type: String,
required: true
},
},
{
timestamps: true
});
module.exports = mongoose.model('User', UserSchema);
This will ensure that emails are unique. Then at the register method, you do this:
exports.register = function(req, res, next){
let name = req.body.name;
let email = req.body.email;
User.findOne({email: email}, function(err, existingUser){
if(err){
return res.status(500).json(err);
}
if(existingUser){
return res.status(422).json('Email address is already registered.');
}
else {
var user = new User({
username : username,
email: email,
password: password
});
user.save(function(err, user){
if(err){
return next(err);
}
var userInfo = setUserInfo(user);
res.status(201).json({
token: 'JWT ' + generateToken(userInfo),
user: userInfo
})
});
}
});
}
}
}
Hope this helps.

How to add to User Object Node.JS

I'm new to node so bear with me!
I am working on my auth system. I have login, register and logout done so far. Now I want to update my user in the settings page. How would I go about updating the already added User items such as username, password and email? And most importantly adding new ones such as API Key, and API Secret.
Here is my code:
var UserSchema = mongoose.Schema({
username: {
type: String,
index:true
},
email: {
type: String
},
password: {
type: String
},
apiKey: {
type: String
},
apiSecret: {
type: String
}
});
My user schema, the api key info is not added on registration. Should it be in the schema or will it be added automatically later?
var newUser = new User({
username: username,
email:email,
password: password
});
User.createUser(newUser, function(err, user){
if(err) throw err;
console.log(user);
req.flash('success_msg', 'You are registered and can now login');
res.redirect('/users/login');
});
How I create the new user after verification.
router.post('/settings', function(req, res){
var apiKey = req.body.apiKey;
var apiSecret = req.body.apiSecret;
//INSERT api info into DB here
});
Where I get the API keys from a form and then want to insert them into the User that is currently logged in. This is where my problem is.
Thank you in advance for any help!
Assuming you've access to the logged in user in req like req.user
router.post('/settings', function(req, res) {
var updateFields = {
apiKey: req.body.apiKey,
apiSecret: req.body.apiSecret
}
User.findOneAndUpdate({"_id": req.user._id}, {"$set": updateFields}, {"new": true}})
.exec(function(err, user) {
if (err) {
//handle err
} else {
//user contains updated user document
}
});
});
And yes you should keep all the fields you want to insert even in future in the schema. Else they won't insert into database.

Cannot call method 'findOne' of undefined at Object.module.exports

Need to knoe why I'mgetting this error? is my approach for validating the user thorugh login form correct here? I'm just new to node.js need your help.
var mongo = require('mongodb');
var mongoose = require('mongoose');
var db = mongoose.connect('mongodb://localhost/subscribe');
var mySchema = new mongoose.Schema({
_id : String,
name : String,
phone : String,
age : Number,
password : String
});
var User = mongoose.model('signups', mySchema);
Signup form , to save the registered user in the mongodb collection.
router.post('/signup', function(req, res) {
var user = new User({
_id : req.body.email,
phone : req.body.phone,
age : req.body.age,
password : req.body.password
});
user.save(function (err, doc) {
if (err) {
res.send("There was a problem adding the information to the database.");
}
else {
res.redirect('/');
}
});
});
trying to validate the user credentials
router.post('/adduser',function(req, res){
db.signups.findOne({ $and: [{_id: req.body.useremail}, {password: req.body.password }]}, function(err, item) {
if (err) return res.send("Please provide valid credentials.");
else {
res.redirect('/home');
}
});
});
How to validate the user credentials here?

Node>Expressjs res.render not redirecting

I am developing application with nodejs and express. I have login page. I am posting user data and if there is no user with that data then i want to redirect page. But res.render not working(I added comment where res.render is in my code like "//Redirect if user not found". Have no idea. Here is my code:
var mongoose = require('mongoose');
mongoose.connect("mongodb://localhost/fuatblog");
var UserSchema = new mongoose.Schema({
name: String,
email: String,
password: String,
age: Number
}),
Users = mongoose.model('Users', UserSchema);
app.post('/sessions', function (req, res) {
console.log(req.body.user.email);
console.log(req.body.user.password);
Users.find({
email: req.body.user.email,
password: req.body.user.password
}, function (err, docs) {
if (! docs.length) {
// no results...
console.log('User Not Found');
//res.status(400);
//Redirect if user not found
return res.render(__dirname + "/views/login", {
title: 'Giriş',
stylesheet: 'login',
error: 'Email or password is wrong.'
});
}
console.log('User found');
req.session.email = docs[0].email;
console.log(req.session.email);
});
return res.redirect('/Management/Index');
});
The .render method which you want to be invoke when the user is not recognized is in async code. This means that the return res.redirect('/Management/Index'); is called once the request reaches your server. But you should do that once you get the result from Users.find. I.e.:
app.post('/sessions', function (req, res) {
console.log(req.body.user.email);
console.log(req.body.user.password);
Users.find({
email: req.body.user.email,
password: req.body.user.password
}, function (err, docs) {
if (! docs.length) {
// no results...
console.log('User Not Found');
//res.status(400);
//Redirect if user not found
return res.render(__dirname + "/views/login", {
title: 'Giriş',
stylesheet: 'login',
error: 'Email or password is wrong.'
});
}
console.log('User found');
req.session.email = docs[0].email;
console.log(req.session.email);
return res.redirect('/Management/Index');
});
});

Resources