Node Async not executing the db function - node.js

I am sending a post request from a form but async.waterfall() doesn't execute the mongoose's User.find() function to fetch users from the database and as a result the post request's status in the network inspector is pending as res.send() is not being called.
exports.createUser = function(req,res){
var email1 = req.body.mail.toString();
var password = req.body.password.toString();
async.waterfall([
function(callback) {
// verify user in the db
User.find({email:email1},function(err,data){
if (err){
res.send(404);
return callback(err);
}
// user is found
if (data.length != 0){
res.send(404);
return callback(new Error("User Found"));
}
callback();
});
},
// generate salt password
function(callback) {
bcrypt.genSalt(SALT_WORK_FACTOR,function(err,salt){
if (err) return callback(err);
bcrypt.hash(password,salt,function(err,hash){
if (err) return callback(err);
return callback(null,hash);
});
});
},
//generate random string
function(hash,callback){
crypto.randomBytes(48,function(err,buf){
if (err) return callback(err);
var randomString = buf.toString('hex');
return callback(null,hash,randomString);
});
},
// save them in the mongoDb using mongoose
function(hash,randomString,callback){
var userModel = new User;
userModel.email = email1;
userModel.password = hash;
userModel.verificationId = randomString;
userModel.save();
callback(null,'done');
}
],function(err){
if (err){
console.log(err);
res.send(404);
} else{
console.log("done");
res.send("200");
}
});
}
Here is my app.js file using express
// render the registration page
app.get('/users/create',register.renderUserPage);
app.post('/users/create',function(req,res){
register.createUser(req,res);
});
Here is the Db.js file which connects to mongoDb using mongoose
console.log("connection succeeded");
var UserSchema = new Schema ({
email: {type:String ,require : true ,index : {unique : true}} ,
password:{ type : String ,required: true} ,
verificationId:{type:String, required:true,index:true}
});
UserSchema.plugin(ttl,{ttl:90000000});
module.exports = mongoose.model('User',UserSchema);

Related

Mongoose findOne function is not working with authentication

I am working on a model here:
// user.js
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var bcrypt = require('bcrypt');
// Define collection and schema for Users
let User = new Schema(
{
firstName: String,
lastName: String,
emailaddress: String,
password: String,
},
{
collection: 'users'
}
);
// authenticate input against database documents
User.statics.authenticate = ((emailaddress, password, callback) => {
User.findOne({ emailaddress: emailaddress })
.exec(function(error, user){
if(error){
return callback(error)
} else if (!user){
console.log('User not found!');
}
bycrypt.compare(password, user.password, function(err, result){
if(result === true){
return callback(null, user);
} else {
return callback();
}
})
})
});
module.exports = mongoose.model('User', User);
As you can see on my model I put the User.statics.authenticate on my codes to do some authentication. And then on my login.js route file:
const path = require('path');
const express = require('express');
const router = express.Router();
const db = require('../../database/index');
const axios = require('axios');
const User = require('../../database/models/user');
router.get('/', (req, res) => {
console.log('hi there this is working login get');
});
router.post('/', (req, res) => {
var emailaddress = req.body.emailaddress;
var password = req.body.password;
if( emailaddress && password ){
User.authenticate(emailaddress, password, function(err, user){
if(err || !user){
console.log('Wrong email or password!');
} else {
req.session.userId = user._id;
return res.redirect('/');
}
});
} else {
console.log('both fields are required...');
}
});
module.exports = router;
I called the function and then User.authenticate function and also I created the route for root w/c is the sample that I want to protect and redirect the user after login:
router.get('/', (req, res) => {
if(! req.session.userId ){
console.log('You are not authorized to view this page!');
}
User.findById(req.session.userId)
.exect((err, user) => {
if(err){
console.log(err)
} else {
res.redirect('/');
}
})
});
Upon clicking submit on my react form it returns this error:
TypeError: User.findOne is not a function
at Function.User.statics.authenticate (/Users/mac/Documents/monkeys/database/models/user.js:35:8)
I checked the Mongoose documentation and it seems I am using the right syntax.Any idea what am I doing wrong here? Please help! Sorry super beginner here!
PS. I've already installed and set up the basic express session too.
UPDATES:
I remove the arrow function from my call and use this.model.findOne but still get the typerror findOne is not a function
// authenticate input against database documents
User.statics.authenticate = function(emailaddress, password, callback){
this.model.findOne({ emailaddress: emailaddress })
.exec(function(error, user){
if(error){
return callback(error)
} else if (!user){
console.log('User not found!');
}
bycrypt.compare(password, user.password, function(err, result){
if(result === true){
return callback(null, user);
} else {
return callback();
}
})
})
};
findOne is a method on your User model, not your user model instance. It provides its async results to the caller via callback:
User.findOne({field:'value'}, function(err, doc) { ... });

Mongoose referencing _id not working

This is my code for a login route, I am trying to call docs._id but it gives me back null. When I call just docs it shows this on server side:
[ { _id: EX unique id,
username: { user: 'EXUsername', search: 'exusername' },
pass: 'EXpassword',
email: 'EXemail' } ]
I am really confused on why I can't call docs.pass or docs._id at all but docs itself has stuff in it and I can call docs and it gives data back.
my code in node.js:
router.post('/loginUser', function(req, res){
CheckingLogin(req.db, req.body.username, req.body.password, function(bool, docs){
if(bool && exists(docs)){
var err = false;
var handleError = function(e){
if(err){
err = true;
var eDoc = {};
eDoc.errorCode = 1;
eDoc.error = e;
console.log(eDoc);
}
}
/////problem here//////////////////////////////////
var userID = docs._id;
console.log(docs._id);
if(userID != null){
if(!err){
tokens.db = req.db;
tokens.refresher.create(userID, function(token){
console.log('in token refresher ' + docs);
res.send('1');
});
}else{
console.log('Token err = true');
}
}else{
console.log('Creator token = null');
res.send('0');
}
}else{
res.send('0');
}
});
});
Hey its an array of object so just get it like this docs[0]._id it will work for you.

Cannot read property 'collection' of undefined while connecting to mongodb in node.js?

I am trying to login from my signin.ejs file,after click on the login button in
my signin page it shows "Cannot read property collection undefined" what is the
problem.
I defined my route like this in app.js:
app.post('/login', routes.dologin);
I defined my dologin route in index.js:
exports.dologin = function (req, res) {
res.locals.session = req.session;
var user = req.body.user;
db.authenticateUser(user.email, user.password, function ( err, response) {
if (err) {
.......
.......
} else {
.......
........
}
});
};
In my db.js:
var mongo = require('mongoskin'),
crypto = require('crypto');
module.exports = function (config) {
var USERS_COLLECTION = 'users',
ORDERS_COLLECTION = 'orders',
salt = 'supersecretkey',
db;
authenticateUser: function (emailId, password, callback) {
db.collection(USERS_COLLECTION).count({email : emailId, password: encryptPassword(password)}, function (err, count) {
if (err) {
console.log("error authenticating user: " + err);
callback(new Error(err));
} else if (count === 0) {
callback(new Error("emailid/password did not match"));
} else {
callback(null);
}
});
},
}
What is the problem here for getting "Collection undefined"? i think here
everything is right... Is there any problem here?tell me..please Thanks.
You should add this code db = mongo.db('localhost:27017/yourdb');
var mongo = require('mongoskin'),
crypto = require('crypto');
module.exports = function (config) {
var USERS_COLLECTION = 'users',
ORDERS_COLLECTION = 'orders',
salt = 'supersecretkey',
db = mongo.db('localhost:27017/yourdb');
authenticateUser: function (emailId, password, callback) {
db.collection(USERS_COLLECTION).count({
email: emailId,
password: encryptPassword(password)
}, function (err, count) {
if (err) {
console.log("error authenticating user: " + err);
callback(new Error(err));
} else if (count === 0) {
callback(new Error("emailid/password did not match"));
} else {
callback(null);
}
});
},
}

NodeJs + Postgres synchronus connection to Database to populate variable

I'm using nodeJs express 3 framework with postgreSQL, I'm using the script below to look for a username in DB and populate a variable so I can pass it to my view.
Here is my script :
app.js
var app = express();
app.use(express.bodyParser());
......
function fncCheckUsernameAvailability(vstrUsername){
var pg = require("pg");
var client = new pg.Client({user: 'xxx', password: 'xxxx', database: 'xxx', host: 'example.com'});
var response = "";
client.connect(function(err) {
if(err) {
return console.error('could not connect to postgres', err);
}
client.query("SELECT username FROM users WHERE username ='"+vstrUsername+"'", function(err, result) {
if(err) {
return console.error('error running query', err);
}
if(result.rows[0] == undefined){
//console.log("Username available");
response = "Username available";//Populating The variable here
}else{
//console.log("Username already taken");
response = "Username already taken";//Populating The variable here
}
client.end();
});
});
return response;
}
app.post("/Signup", function(req, res){
var username = req.body.username;
var Response = fncCheckUsernameAvailability(username);
console.log(Response);
}
The response variable is allways "undefined", so how can I make that script waiting until the DB checking is done to populate the "response" variable?
You cannot place return values into asynchronous functions. You would instead need to use a callback, and this is what your code might look like:
function fncCheckUsernameAvailability(vstrUsername, callback) {
client.connect(function(err) {
if (err) {
callback(err, null);
return;
}
client.query("SELECT username FROM users WHERE username ='" + vstrUsername + "'", function (err, result) {
client.end();
if (err) {
callback(err, null);
return;
}
if (result.rows[0] == undefined) callback(null, 'Username available.');
else callback(null, 'Username taken.');
});
});
};
You would use the function like this:
app.post("/Signup", function(req, res) {
var username = req.body.username;
fncCheckUsernameAvailability(username, function(err, result) {
console.log(result);
});
});

how to get all users in redis

I have the following code .
var redis = require("redis"),
client = redis.createClient();
user_rahul = {
username: 'rahul'
};
user_namita = {
username: 'namita'
};
client.hmset('users.rahul', user_rahul);
client.hmset('users.namita', user_namita);
var username = "rahul"; // From a POST perhaps
client.hgetall("users" , function(err, user) {
console.log(user);
});
I want to get all the users list how i can get all users list this what i tried but its not working.
You are setting the users in their own hash, so when you do hgetall users, you are trying to get all the members of the users hash. You should do:
var redis = require("redis"),
client = redis.createClient();
user_rahul = {
username: 'rahul'
};
user_namita = {
username: 'namita'
};
client.hset('users', user_rahul, 'Another Value, Pass Maybe?');
client.hset('users', user_namita, 'Another Value, Pass Maybe?');
var username = "rahul"; // From a POST perhaps
client.hgetall("users" , function(err, user) {
console.log(user);
});
You should consider using a list instead, if you dont need any data in the second hash value
How about this
var flow = require('flow'); //for async calls
var redis = require("redis").createClient();
function AddUser(user,callback){
flow.exec(
function(){
//AI for Keep unique
redis.incr('nextUserId',this);
},
function(err,userId){
if(err) throw err;
this.userId = userId;
redis.lpush('users',userId,this.MULTI());
redis.hmset('user:'+userId+':profile',user,MULTI());
},
function(results){
results.forEach(function(result){
if(result[0]) throw result[0];
});
callback(this.userId);
}
);
}
user_rahul = {username: 'rahul'};
user_namita = {username: 'namita'};
//Add user
AddUser(user_rahul,function(userId){
console.log('user Rahul Id' + userId);
});
AddUser(user_namita,function(userId){
console.log('user Namita Id' + userId);
});
//users
function Users(callback){
var users = [];
flow.exec(
function(){
redis.lrange('users',0,-1,this);
},
function(err,userIds){
if(err) throw err;
flow.serialForEach(userIds,function(userId){
redis.hgetall('user:'+userId+':profile',this);
},
function(err,val){
if(err) throw err;
users.push(val);
},
function(){
callback(users);
});
}
);
}
//call
Users(function(users){
console.log(users);
});
For Single User
function getUser(userId,callback){
redis.hgetall('user:'+ userId +':profile',function(err,profile){
if(err) throw err;
callback(profile);
});
}
getUser(1,function(profile){
console.log(profile);
});

Resources