Why I'm getting two responses from find query? - node.js

I'm trying to check if user exists in MongoDb.
For unknown reason after I found that the user exsists and send response , it's logging me that the user does not exsists
app.post("/login", function(req, res) {
var userName = req.body.userName;
var pass = req.body.pass;
console.log('')
console.log('Try to login:')
console.log('userName: ' + userName);
console.log('pass: ' + pass);
if(req.body.userName && req.body.pass)
{
db.collection("customers").find({first_name:userName}, function(err, docs) {
docs.each(function(err, doc)
{
if(doc) {
//console.log(doc);
console.log('User Exsists')
res.send('YES');
}
else {
console.log('User Does Not Exsists')
res.end();
}
})});
}
else
{
console.log('NO')
res.send('NO')
}
});
Output: (first users not exists and the second does exists)
Try to login:
userName: sdlkj
pass: lkj
User Does Not Exsists
Try to login:
userName: sivan
pass: lkj
User Exsists
User Does Not Exsists
Why after I found that the user exists I'm getting another log line which it does not found ?

This is happening because you're iterating over the result cursor using each, which calls its callback one final time with a parameter value of null to signal that the cursor is exhausted.
Instead, you probably want to be using findOne here:
db.collection("customers").findOne({first_name: userName}, function(err, doc) {
if(doc) {
console.log('User Exsists')
res.send('YES');
}
else {
console.log('User Does Not Exsists')
res.end();
}
});

Related

How to disallow disabled users from logging in, into a page using passport.js?

I've used a soft delete feature in mongodB to disable a user and not delete it permanently. Now, only enabled users can log in to the site while the disabled users can not log in to the site.
// Soft delete feature
exports.getDisabledUsers = function(req,res, next) {
User.find({active: false}, function(err, users) {
if (err) {
res.send(err);
}
res.json(users);
});
}
// Log In
exports.login = function (req, res, next) {
var userInfo = setUserInfo(req.user);
res.status(200).json({
token: 'JWT ' + generateToken(userInfo),
user: userInfo
});
};
// Passport.js
var localLogin = new LocalStrategy(localOptions, function (email, password, done) {
User.findOne({
email: email
}, function (err, user) {
if (err) {
return done(err);
}
if (!user) {
return done(null, false, {
error: 'Login failed. Please try again.'
});
}
user.comparePassword(password, function (err, isMatch) {
if (err) {
return done(err);
}
if (!isMatch) {
return done(null, false, {
error: 'Login failed. Please try again.'
});
}
return done(null, user);
});
});
});
Disabled users shouldn't be able to log in. Right now, they are able to log in.
While Disabling the user you can move that data to another collection, that way your disabled user cannot be able to login to your system
exports.disableUser = function (req, res, next) {
User.findByIdAndUpdate({_id:req.params._id}, {active: false}, function (err, users) {
if (err) {
res.send(err);
}
User.findByIdAndRemove(
{_id:req.params._id},
function(err, doc) {
if (doc) {
DisableUser.insertMany(doc, function(err, doc){
// your response
});
} else {
// your response
}
)
});
}
You have not checked user status is active or not. This can be done by adding a condition in code, or modifying mongo query and adding one more condition in findOne.
//CODE
if(!user.active) {
//RETURN USER IS NOT ACTIVE
}
//MONGO QUERY
User.findOne({
email: email,
active: true
}, function (err, user) {
//YOUR CODE
}
Role based login may create some complexity but this can be achieved simply by adding one more collection named disabledUsers
when admin disable any user then the click function do two things at the same time
1)add the email into disabledUser collection
2)delete the user from user collection
Then in your login function just check this way
disabledUser.findOne({email :email },
function (err ,user){
if(err) return done(err)
else{
if(!user){
user.findOne({email : email }
write your login stuff here the wau you r doing
}
else{return alert('user is disabled')}
}
})

Node.js - Check if user exists

I'm using NodeJS and passport to let users create an account before they can see results of a quiz they've just taken. My challenge is I need to confirm the username is available before the page refreshes because the user will lose their results if this happens.
Again: I need to verify the username is not taken prior to refreshing.
I think I'm close but it is not working. How would I change my code to handle this challenge?
Currently if the user name is taken it returns an error on trying to create an account and the user ends up on the /failpage as shown below.
app.post('/quiz', usernameToLowerCase, emailToLowerCase, function(req, res) {
User.findOne({
username: req.body.username
}, function(err, user) {
if (err) {
alert(err)
if (user) {
alert('this username is already taken. Please choose another.')
console.log('there was a user');
return false;
}
}
});
var user = new User({
username: req.body.username,
email: req.body.email,
password: req.body.password,
})
user.save(function(err) {
console.log('this is the problem' + ' ' + err)
if (err) {
return res.redirect('/failpage')
}
req.logIn(user, function(err) {
if (err) {
console.log(err);
}
console.log('all looks good')
res.redirect('/results');
});
});
});
Solved it with this if anyone else is trying to do the same thing:
in app.js
app.get('/usercheck', function(req, res) {
User.findOne({username: req.query.username}, function(err, user){
if(err) {
console.log(err);
}
var message;
if(user) {
console.log(user)
message = "user exists";
console.log(message)
} else {
message= "user doesn't exist";
console.log(message)
}
res.json({message: message});
});
});
In js
$('#usercheck').on('change', function() {
$.get('/usercheck?username='+$('#usernameValue').val().toLowerCase(), function(response) {
$('#usernameResponseHidden').text(response.message)
if ($('#usernameResponseHidden').html() === "user exists"){
$('#usernameResponse').text('That username is taken. Please pick another')
}
To solve your problem I think you need to routes. At least a app.get('/quiz') which returns a boolean on if the user exists or not. The section User.findOne can be sent in that route instead. You just need to make a request using ajax when he looses focus of the username field of your form, and display a notification if the name is available or not.

Node.Js Mean Stack, Save method always return "User Already Exists"

I am learning NodeJs Mean Stack and was working with Mean.Js sample app,
Everything works fine and I am able to create first user with the sign up form. But creating another user always give me "User name Alreay Exists" message. I've applied check on the code before save to see if user already exists ore not and mongoose findOne method returns me null(and he is right because user with the provided username does not exist) but save method still gives error, user already exist
here is my sign up code:
/**
* Signup
*/
exports.signup = function(req, res) {
// For security measurement we remove the roles from the req.body object
delete req.body.roles;
// Init Variables
var user = new User(req.body);
var message = null;
// Add missing user fields
user.provider = 'local';
user.displayName = user.firstName + ' ' + user.lastName;
User.findOne({
"username": user.username
}, function(oerr, dbUser) {
if (oerr) {
return res.status(400).send({
message: errorHandler.getErrorMessage(err) + ' user Name' + user.username
});
}
if (dbUser === null) {
// Then save the user
user.save(function(err) {
if (err) {
return res.status(400).send({
message: errorHandler.getErrorMessage(err) + ' user Name' + user.username
});
} else {
// Remove sensitive data before login
user.password = undefined;
user.salt = undefined;
req.login(user, function(err) {
if (err) {
res.status(400).send(err);
} else {
res.json(user);
}
});
}
});
} else {
return res.status(400).send({
message: "This User Already Exist Buddy. " + ' user Name' + user.username
});
}
});
};
Thanks

mongo not showing users even though I "know" they exist

I am trying to implement a authentication system for my website using MEAN however I have run into a relatively strange problem. I am able to register users and duplicate usernames can be identified. However, I cannot get logging into the website working. When I search the mongo database using the command line, I do not get anything. This is what my mongo output looks like.
>> show users
>>
The database has the username somewhere... so how do I get the users to be properly displayed? Why is that user is undefined when I try to log in even though I know the username is in the database?
var crypto = require('crypto');
var mongoose = require('mongoose');
var User = mongoose.model('User');
function hashPW(pwd) {
return crypto.createHash('sha256').update(pwd).digest('base64').toString();
};
module.exports.signup = function (req,res) {
var user = new User({username:req.body.usernmae});
console.log('made it here');
user.set('hashed_password', hashPW(req.body.password));
user.set('email', req.body.email);
user.save(function (err) {
if (err) {
try {
if (err.code==11000) res.render('signup', {message: 'Sorry, someone has that username already.'})
} catch(e) {
}
console.log(err);
//res.redirect('/signup');
} else {
req.session.user = user.id;
req.session.username = user.username;
req.session.msg = 'Authenticated as ' + user.username;
res.redirect('/');
}
});
};
module.exports.login = function (req,res) {
User.findOne({ username: req.body.username })
.exec(function(err,user) {
console.log(user);
console.log(err);
console.log(hashPW(req.body.password.toString()));
if (!user) {
err = 'User Not Found.';
} else if ( user.password === hashPW( req.body.password.toString() ) ) {
req.session.regenerate(function() {
req.session.user = user.id;
req.session.username = user.username;
req.session.msg = 'Authenticated as ' + user.username;
res.redirect('/');
});
} else {
err = 'Authentication failed.';
}
if (err) {
console.log(err);
req.session.regenerate(function() {
req.session.msg = err;
res.redirect('/login');
});
}
});
};
I notice that there's a typo in the provided code.
var user = new User({username:req.body.usernmae});
Should likely read
var user = new User({username:req.body.username});
This probably meant the name failed to set thus putting a junk user into your DB.
Also, regarding your command in the Mongo Shell, Neil's answer covered that the show command is not actually useful here. The reference for db.collection.find() is here.
silly mistake. the field is not password but hashed_password.
{ email: 'somerandomemail#gmail.com',
hashed_password: 'A8ctR3JAA84DWTmYXEAhxEEP1bTtAidaoyWArKHtk2g=',
username: 'Szpok',
_id: 54c09c458c4eccc90b9c4bb5,
__v: 0 }

Mongodb findone query in node.js & express times out

I'm trying to find one user in a db where password and username matches. If I write the correct username and password everything works smoothly. But if I write the wrong password for instance I get a timeout after about one minute.
Any suggestions of how I could fix this?
exports.bsLogin = function(req, res) {
console.log('************ bslogin ************');
var body = req.body;
var username2 = body.username;
var password2 = body.password;
db.collection('users', function(err, collection) {
collection.findOne({username:username2, password:password2}, function(err, item) {
if (err) {
res.render('bslogin',
{ title : 'Hello', error : 'Username or Password is incorrect' }
);
return;
}
if (item) {
res.writeHead(302, {
'Location': '/backstageArea'
});
res.end();
}
});
});
};
It's timing out because no response is being given when there is neither an err nor an item.
Based on the current responses, the 1st if could probably be modified to handle both MongoDB errors and lack of items:
if (err || !item) {
res.render('bslogin',
{ title : 'Hello', error : 'Username or Password is incorrect' }
);
return;
}
Or, add an else block to respond to each scenario separately:
if (err) {
/* ... */
} else if (item) {
/* ... */
} else {
/* ... */
}

Resources