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?
Related
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.
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.
I am creating an application for online course.
I have created a schema for user registration. In the schema, I also want to add the name of courses a user in enrolled. Course Name being an array.
User registration is successful. after that I have created a route for /dashboard, where the user sends the POST request to add the course name. That course should be added in the same registration schema field for course Enrolled. However When I save a new object of registration schema, it creates a new document field courseEnrolled field. I want this POST request value to be added in the user's document field of courseEnrolled as an array.
Here is how I have defined my registration schema. Its name in account.js
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var passportLocalMongoose = require('passport-local-mongoose');
var courseSchema = new Schema({ courseName : String });
var Account = new Schema({
username: {
type: String,
unique: true
},
password: String,
email: String,
firstName: String,
lastName: String,
courseEnrolled: [{courseName : String}]
});
Account.plugin(passportLocalMongoose);
module.exports = mongoose.model('Account', Account);
Here is my passport registration . register.js
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
var User = require('../models/account');
var bCrypt = require('bcrypt-nodejs');
var course = require('../models/courseEnrollment');
module.exports = function(passport){
passport.use('register', new LocalStrategy({
passReqToCallback : true // allows us to pass back the entire request to the callback
},
function(req, username, password, done) {
findOrCreateUser = function(){
// find a user in Mongo with provided username
User.findOne({ 'username' : username }, function(err, user) {
// In case of any error, return using the done method
if (err){
console.log('Error in SignUp: '+err);
return done(err);
}
// already exists
if (user) {
console.log('User already exists with username: '+username);
return done(null, false, req.flash('message','User Already Exists'));
} else {
// if there is no user with that email
// create the user
var newUser = new User();
var newCourse = new course();
// set the user's local credentials
newUser.username = username;
newUser.password = createHash(password);
newUser.email = req.body.email;
newUser.firstName = req.body.firstName;
newUser.lastName = req.body.lastName;
newUser.courseEnrolled = req.body.courseEnrolled;
// save the user
newUser.save(function(err) {
if (err){
console.log('Error in Saving user: '+err);
throw err;
}
console.log('User Registration succesful');
return done(null, newUser);
});
}
});
};
// Delay the execution of findOrCreateUser and execute the method
// in the next tick of the event loop
process.nextTick(findOrCreateUser);
})
);
// Generates hash using bCrypt
var createHash = function(password){
return bCrypt.hashSync(password, bCrypt.genSaltSync(10), null);
}
}
I can register a user successfully. After that I have a route for /dashboard, where I handle the POST request to add a course.
Here is the snippet of my /dashboard handling POST request.
var User = require('../models/account');
/* POST dashboard Page */
router.post('/dashboard', isAuthenticated, function (req, res) {
sess = req.session.passport.user;
console.log('session value is: ' + sess);
var newUser = new User();
console.log('newUser id is: ' + newUser._id);
var currentUser = req.user._id;
console.log('current User id is: ' + currentUser);
var myUser = req.user;
console.log('myUsers value is: ' + myUser);
var myUserCourse = req.user.courseEnrolled;
if (sess == currentUser) {
//var newCourse = new course();
console.log('request received: ' + req.body.courseEnrolled);
req.user.courseEnrolled = req.body.courseEnrolled;
newUser.save(function (err, data) {
if(error)
throw error;
else {
console.log('course Updated');
}
});
res.render('home', {user: req.user});
}
});
This newUser.save() function creates a new document in the mongodb and store the courseEnrolled. I want to store the value of req.body.courseEnrolled in the same document field where other user value is defined.
This is getting stored in collection:- 'accounts' for the user
{
"_id" : ObjectId("57f95afd9c78b91c69334f0d"),
"lastName" : "Nehra",
"firstName" : "Ashish",
"email" : "ashish.nehra#stanford.edu",
"password" : "$2a$10$YzLvbQTHFtq5l0ooP0njOux94Rp.pm.Pkb/TugBnCSTUJNhBBonLG",
"username" : "ashish",
"courseEnrolled" : [
"about to change something now"
],
"__v" : 1
}
And there is a new document being created like this in the same collection.
{
"_id" : ObjectId("5803fc4342ca1d3167102300"),
"courseEnrolled" : [ ],
"__v" : 0
}
This is logical because first you do a it on various user objects (req.user / new user):
**var newUser = new User();
This will create a new User object, and then:
newUser.save(function (err, data) {
This will save the newly created user into a new document. If you want to use the .save, rewrite it to (reused your own code):
User.findOne({ 'username' : username }, function(err, user) {
// In case of any error, return using the done method
if (err){
console.log('Error in SignUp: '+err);
return done(err);
}
user.courseEnrolled = req.body.courseEnrolled;
user.save(function (err, data) {
if(err)
throw err;
else {
console.log('course Updated');
}
});
I have a simple ExpressJS app and I'm trying to add user authentication to it using passport, passport-local and passport-local-mongoose, but after I save a user's data on db, mongoose fails to retrieve it, although I can see the data through mongo cli.
At the main express module I have:
// Passport session setup.
var User = require("./models/user");
passport.use(new LocalStrategy(User.authenticate()));
passport.serializeUser(User.serializeUser());
passport.deserializeUser(User.deserializeUser());
My User model module have:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var passportLocalMongoose = require('passport-local-mongoose');
// User Schema
var User = new Schema({
username: { type: String, required: true, unique: true },
password: { type: String, required: true}
});
User.plugin(passportLocalMongoose);
module.exports = mongoose.model('User', User);
At my routes module, I create a user with the following code:
router.post('/register', function(req, res) {
var u = req.body.username;
var p = req.body.password;
console.log('Creating account for ' + u + ':' + p);
// Store client on DB
var usr = new User({ username: u, password: p });
usr.save(function(err) {
if(err) {
console.log(err);
return res.render('register', {title: 'Register', error: err.userMessage});
} else {
console.log('user: ' + usr.username + " saved.");
passport.authenticate('local')(req, res, function () {
return res.redirect('/dashboard');
});
}
});
});
But when I try to authenticate a user with the passport.authenticate method, mongoose cannot find the user at the db, as I can see on the mongoose logs:
Login request # 1422120637815
Mongoose: users.findOne({ username: 'e#e.com' }) { fields: undefined }
But at mongo cli I can see the data:
> db.User.find()
{ "username" : "e#e.com", "password" : "123", "_id" : ObjectId("54c3d688fc71a4001db30612"), "__v" : 0 }
Mongoose is looking for a collection named 'users', but it looks like your data is stored in 'User'. The API for model() is mongoose#model(name, [schema], [collection], [skipInit]). so you can force the collection name by adding a third parameter e.g.
module.exports = mongoose.model('User', User, 'User');
EDIT1:
Try using the built-in register() method in mongoose-local
router.post('/register', function(req, res) {
var u = req.body.username;
var p = req.body.password;
console.log('Creating account for ' + u + ':' + p);
// Store client on DB
Account.register(new Account({ username: req.body.username }), req.body.password, function(err) {
if(err) {
console.log(err);
return res.render('register', {title: 'Register', error: err.userMessage});
} else {
passport.authenticate('local')(req, res, function () {
return res.redirect('/dashboard');
});
}
});
});
I'm trying to set up a verification step in Mongoose, Express Node application based on this blog post ... http://danielstudds.com/adding-verify-urls-to-an-express-js-app-to-confirm-user-emails-secure-spa-part-6/ that post is over a year old so it kind of surprises me that its the first google result for 'node email verification'. I'm very new to node so I'm reliant on examples. Based on that post I did not see a download so I pieced it together to suit my scenario and here is what my code looks like.
Verification Model
var mongoose = require('mongoose'),
uuid = require('node-uuid'),
User = require('mongoose').model('User');
var verificationTokenSchema = new mongoose.Schema({
_userid : { type: mongoose.Schema.Types.ObjectId, ref: 'User' },
token: {type: String, required: true},
createdAt: {type: Date, required: true, default: Date.now, expires: '4h'}
});
verificationTokenSchema.methods = {
createVerificationToken : function (done) {
var verificationToken = this;
var token = uuid.v4();
verificationToken.set('token', token);
verificationToken.save( function (err) {
if (err) return done(err);
return done(null, token);
});
}
};
exports.verifyUser = function(token, done) {
verificationTokenModel.findOne({token: token}, function (err, doc){
if (err) return done(err);
User.findOne({_id: doc._userId}, function (err, user) {
if (err) return done(err);
user["verified"] = true;
user.save(function(err) {
done(err);
});
});
});
};
var verificationTokenModel = mongoose.model('VerificationToken', verificationTokenSchema);
exports.verificationTokenModel = verificationTokenModel;
Then in my User model I call create like so..
User Model
exports.createUser = function(req, res, next) {
// Do all the stuff that creates the user save it and get the id back
var verificationToken = new verificationTokenModel({_userId: user._id});
verificationToken.createVerificationToken(function (err, token) {
if (err){
err = new Error("Couldn't create verification token");
res.status(400);
return res.send({reason:err.toString()});
}
// Do stuff with the token here and email
This works 'partially' in my db 'verificationtokens' collection the objects don't contain a _userid they contain the _userid (user._id) stored in _id
My first issue is I don't really understand how this works when there isn't a 'constructor'
var verificationToken = new verificationTokenModel({_userId: user._id});
and how do I get this to store the user._id as _userid in the verification collection
I don't use Mongoose, but here is what it happened:
For your first question:
when you run:
var verificationTokenModel = mongoose.model('VerificationToken', verificationTokenSchema);
it creates the constructor.
For the second question:
MongoDB always create documents with a field called "_id", so, the "_id" field in your verification collection is not the "_id" field from your User collection. The reason that _userid is not inserted is because you have a typo:
var verificationToken = new verificationTokenModel({_userId: user._id});
where "_userId" should be "userid"