the project contains 3 files which are listed below
the thing is happening when i try to change the if from (req.file.profileImage) to (req.file) it works but it always send the default name and not uploading the requested file and if i leave it (req.file.profileImage) if gives an error when i try to submit the form >>
Cannot read property 'profileimage' of undefined
1- users.js
var express = require('express');
var router = express.Router();
var User=require('../models/user.js');
/* GET users listing. */
router.get('/', function(req, res, next) {
res.send('respond with a resource');
});
router.get('/register', function(req, res, next) {
res.render('register', {
'title': 'Register'
});
});
router.get('/login', function(req, res, next) {
res.render('login', {
'title': 'Login'
});
});
router.post('/register', function(req, res, next) {
var name = req.body.name;
var email = req.body.email;
var username = req.body.username;
var password = req.body.password;
var password2 = req.body.password2;
// Check for Image Field
if(req.file.profileimage) {
console.log('uploading File...');
console.log("i am the if" );
// File Info
var profileImageOriginalName = req.file.profileimage.originalname;
var profileImageName = req.file.profileimage.name;
var profileImageMime = req.file.profileimage.mimetype;
var profileImagePath = req.file.profileimage.path;
var profileImageExt = req.file.profileimage.extension;
var profileImageSize = req.file.profileimage.size;
} else {
// Set a Default Image
var profileImageName = 'noimage.png';
console.log("im the else");
}
console.log(req.file);
console.log(profileImageName);
// Form Validation
req.checkBody('name','Name field is required').notEmpty();
req.checkBody('email','Email field is required').notEmpty();
req.checkBody('email','Email not valid').isEmail();
req.checkBody('username','Username field is required').notEmpty();
req.checkBody('password','Password field is required').notEmpty();
req.checkBody('password2','Password do not match').equals(req.body.password);
// Check for errors
var errors = req.validationErrors();
if(errors){
res.render('register', {
errors: errors,
name: name,
email: email,
username: username,
password: password,
password2: password2
});
} else {
var newUser = new User({
name: name,
email: email,
username: username,
password: password,
profileImage: profileImageName
});
}
// Create User
User.createUser(newUser, function(err, user){
if(err)throw err;
console.log(user);
});
//Success Message
req.flash('success', 'You are noew registered and may log in');
res.location('/');
res.redirect('/');
});
module.exports = router;
# 2-models/user.js#
var mongoose = require('mongoose');
//var bcrypt = require('bcrypt');
mongoose.connect('mongodb://localhost/nodeauth');
var db = mongoose.connection;
// User Schema
var UserSchema = mongoose.Schema({
username: {
type: String,
index: true
},
password: {
type: String,
required: true,
bcrypt: true
},
email: {
type: String
},
name: {
type: String
},
profileImage: {
type: String
}
});
var User = module.exports = mongoose.model('User', UserSchema);
module.exports.createUser = function(newUser,callback){
// Create User
newUser.save(callback);
}
# 3-register.jade which containing the form#
extends layout
block content
h1 Register
p Please register using the form below
ul.errors
if errors
each error, i in errors
li.alert.alert-danger #{error.msg}
form(method='post', action='/users/register',endtype='multipart/form-data')
.form-group
label Name
input.form-control(name='name', type='text', placeholder='Enter Name')
.form-group
label Email
input.form-control(name='email', type='email', placeholder='Enter Email')
.form-group
label Username
input.form-control(name='username', type='text', placeholder='Usernamee')
.form-group
label Password
input.form-control(name='password', type='password', placeholder='Enter Password')
.form-group
label Password
input.form-control(name='password2', type='password', placeholder='Confirm Password')
.form-group
label Profile Image
input.form-control(name='profileImage', type='file')
input.btn.btn-default(name='submit', type='submit', values='Register')**
Related
This question already has answers here:
E11000 duplicate key error index in mongodb mongoose
(22 answers)
Closed 3 years ago.
any time i try to register a user it gives me this error
I checked the db collection and no such duplicate entry exists, let me know what I am doing wrong ?
FYI - req.body.email and req.body.password are fetching values.
I also checked this post but no help STACK LINK
If I removed completely then it inserts the document, otherwise it throws error "Duplicate" error even I have an entry in the local.email
Server started on port 5000
MongoDB Connected
MongoError: E11000 duplicate key error collection: test.users index: email1_1 dup key: { email1: null }
{ driver: true,
name: 'MongoError',
index: 0,
code: 11000,
keyPattern: { email1: 1 },
keyValue: { email1: null },
errmsg: 'E11000 duplicate key error collection: test.users index: email1_1 dup key: { email1: null }',
[Symbol(mongoErrorContextSymbol)]: {}
}
Following is my user schema in user.js model
Schema
const mongoose = require('mongoose');
const UserSchema = new mongoose.Schema({
name: {
type: String,
required: true
},
email: {type: String, unique: true, required: true
},
resetPasswordToken: String,
resetPasswordExpires: Date,
password: {
type: String,
required: true
},
date: {
type: Date,
default: Date.now
}
});
const User = mongoose.model('User', UserSchema);
module.exports = User;
Route
const express = require('express');
const router = express.Router();
const bcrypt = require('bcryptjs');
const passport = require('passport');
const async = require("async");
const nodemailer = require("nodemailer");
const crypto = require("crypto");
// Load User model
const User = require('../models/User');
const { forwardAuthenticated } = require('../config/auth');
// Login Page
router.get('/login', forwardAuthenticated, (req, res) => res.render('login'));
// Register Page
router.get('/register', forwardAuthenticated, (req, res) => res.render('register'));
// Register
router.post('/register', (req, res) => {
const { name, email, password, password2 } = req.body;
let errors = [];
if (!name || !email || !password || !password2) {
errors.push({ msg: 'Please enter all fields' });
}
if (password != password2) {
errors.push({ msg: 'Passwords do not match' });
}
if (password.length < 6) {
errors.push({ msg: 'Password must be at least 6 characters' });
}
if (errors.length > 0) {
res.render('register', {
errors,
name,
email,
password,
password2
});
} else {
User.findOne({ email: email }).then(user => {
if (user) {
errors.push({ msg: 'Email already exists' });
res.render('register', {
errors,
name,
email,
password,
password2
});
} else {
const newUser = new User({
name,
email,
password
});
bcrypt.genSalt(10, (err, salt) => {
bcrypt.hash(newUser.password, salt, (err, hash) => {
if (err) throw err;
newUser.password = hash;
newUser
.save()
.then(user => {
req.flash(
'success_msg',
'You are now registered and can log in'
);
res.redirect('/users/login');
})
.catch(err => console.log(err));
});
});
}
});
}
});
// Login
router.post('/login', (req, res, next) => {
passport.authenticate('local', {
successRedirect: '/dashboard',
failureRedirect: '/users/login',
failureFlash: true
})(req, res, next);
});
// Logout
router.get('/logout', (req, res) => {
req.logout();
req.flash('success_msg', 'You are logged out');
res.redirect('/users/login');
});
module.exports = router;
The thing is that, as I see from the error message, it seems like you have one entity in the DB which has no email(basically email = null). And because you've specified email field as unique, mongoDB thinks that not having an email is unique, so there can only be one entity with no email field in the collection. And you're trying to add another entity with no email, and eventually, you have an error, because this entity also has no email as a record in the DB.
You just need to verify if email is present, before sending it to DB, or implement other solution that fits for your business logic.
Hope it helps :)
This is the code I used as I've been learning fullstack online as this is the code they used, but I keep getting the error message that req.checkBody is not a function. I've tried reverting back to an earlier version of express-validator but can't seem to do that either. Apparently express-validator was updated which is why req.checkBody is no longer a function but I can't seem to fix my code.
var express = require('express');
var router = express.Router();
var mongojs = require('mongojs');
var db = mongojs('passportapp', ['users']);
var bcrypt = require('bcryptjs');
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
// Login Page - GET
router.get('/login', function(req, res){
res.render('login');
});
// Register Page - GET
router.get('/register', function(req, res){
res.render('register');
});
// Register - POST
router.post('/register', function(req, res){
// Get Form Values
var name = req.body.name;
var email = req.body.email;
var username = req.body.username;
var password = req.body.password;
var password2 = req.body.password2;
// Validation
req.checkBody('name', 'Name field is required').notEmpty();
req.checkBody('email', 'Email field is required').notEmpty();
req.checkBody('email', 'Please use a valid email address').isEmail();
req.checkBody('username', 'Username field is required').notEmpty();
req.checkBody('password', 'Password field is required').notEmpty();
req.checkBody('password2', 'Passwords do not match').equals(req.body.password);
// Check for errors
var errors = req.validationErrors();
if(errors){
console.log('Form has errors...');
res.render('register', {
errors: errors,
name: name,
email: email,
username:username,
password: password,
password2: password2
});
} else {
var newUser = {
name: name,
email: email,
username:username,
password: password
}
db.users.insert(newUser, function(err, doc){
if(err){
res.send(err);
} else {
console.log('User Added...');
//Success Message
req.flash('success', 'You are registered and can now log in');
// Redirect after register
res.location('/');
res.redirect('/');
}
});
}
});
module.exports = router;
I receive this error:
TypeError: req.check is not a function
at E:\Desktop\website\routes\users.js:22:6
at Layer.handle [as handle_request] (E:\Desktop\website\node_modules\express\lib\router\layer.js:95:5)
at next (E:\Desktop\website\node_modules\express\lib\router\route.js:137:13)
at Route.dispatch (E:\Desktop\website\node_modules\express\lib\router\route.js:112:3)
at Layer.handle [as handle_request] (E:\Desktop\website\node_modules\express\lib\router\layer.js:95:5)
at E:\Desktop\website\node_modules\express\lib\router\index.js:281:22
at Function.process_params (E:\Desktop\website\node_modules\express\lib\router\index.js:335:12)
at next (E:\Desktop\website\node_modules\express\lib\router\index.js:275:10)
at Function.handle (E:\Desktop\website\node_modules\express\lib\router\index.js:174:3)
at router (E:\Desktop\website\node_modules\express\lib\router\index.js:47:12)
Make sure you have installed express-validator:
npm i express-validator
Then import it like so:
var api = express.Router();
var expressValidator = require('express-validator');
api.use(expressValidator())
TypeError: req.checkBody is not a function including bodyparser and expressvalidator module
Export validations as par your validation module you can use express-validator or many more currently I am using validator and return errors object.
create File validateRegisterInput.js change syntax based on your ES version and ts
const Validator = require('validator')
module.exports = function validateRegisterInput(data) {
let errors = {}
data.email = data.email ? data.email : ''
data.password = data.password ? data.password : ''
if (!Validator.isEmail(data.email)) {
errors.email = 'Email is invalid'
}
if (Validator.isEmpty(data.email)) {
errors.email = 'Email is required'
}
if (!Validator.isLength(data.password, { min: 6, max: 30 })) {
errors.password = 'Password must have 6 chars'
}
....... // do more validation here
return {
errors,
isValid: isEmpty(errors)
}
}
On route.js file import
const validateRegisterInput = require('./middleware/validateRegisterInput')
....
router.post('/register', (req, res) => {
const { errors, isValid } = validateRegisterInput(req.body)
if (!isValid) {
return res.status(400).json({
'response_code': 400,
'message': 'error',
'errors': errors
})
} else {
// create User
}
})
I did the registration portion successfully now I am trying to delete the registered user by id . This is how I did
user controller
const mongoose = require ('mongoose');
const User = mongoose.model('User');
module.exports.register = (req, res, next) =>{
var user = new User();
user.fullName = req.body.fullName;
user.email = req.body.email;
user.password = req.body.password;
user.phoneNumber = req.body.phoneNumber;
user.save((err, doc) =>{
if(!err)
res.send(doc);
else{
if (err.code == 11000)
res.status(422).send(["Entered duplicate email address. Please check"]);
else
return next(err);
}
});
}
And in my index router
const express = require ('express');
const router = express.Router();
const ctrlUser = require ('../controllers/user.controller.js');
// routing functions
router.post('/register' , ctrlUser.register);
router.delete('/:userId' , (req, res, next) =>{
User.remove({_id: req.params.userId})
.exec()
.then(result => {
res.status(200).send(["Deleted"]);
})
.catch(err =>{
if (err.code == 500)
res.status(500).send(["Didn't get deleted"]);
else
return next(err);
});
});
module.exports = router;
When I am testing in postman I am not getting any response. Where did I make the mistake ? Something am I missing out ?
EDIT:- Including user.model
const mongoose = require ('mongoose');
const bcrypt = require('bcryptjs');
//define user schema
var userSchema = new mongoose.Schema({
fullName : {
type: String,
required: "Full name can't be empty"
},
email : {
type: String,
required: "Email can't be empty",
unique: true
},
password : {
type: String,
required: "Password can't be empty",
minlength: [6 ,"Password must be atleast 6 character long"]
},
phoneNumber : {
type: String,
required: "Reqired for further contact.Can't be empty"
},
saltSecret: String //this is user for encryption and decryption of password
});
mongoose.model('User', userSchema);
I have been battling with this for some time now, I have this Nodejs Express app and my registration form returns a bunch of validation errors when the form fields are invalid which is a good thing but however, when the form is properly filled it still returns these errors and doesn't submit any data.
This is the code route.post for register
router.post('/register', function(req, res, next){
var name = req.body.name;
var email = req.body.email;
var username = req.body.username;
var password = req.body.password;
var password2 = req.body.password2;
// Check for image field
if(req.files && req.files.profileimage){
console.log('Uploading File...');
// File Info
var profileImageOriginalName = req.files.profileimage.originalname;
var profileImageName = req.files.profileimage.name;
var profileImageMime = req.files.profileimage.mimetype;
var profileImagePath = req.file.profileimage.path;
var profileImageExt = req.files.profileimage.extension;
var profileImageSize = req.files.profileimage.size;
}else {
// Set a Default Image
var profileImageName = 'noimage.png';
}
// Form validation
req.checkBody('name', 'Name is required').notEmpty();
req.checkBody('email', 'Email is required').notEmpty();
req.checkBody('email', 'Invalid Email ID').isEmail();
req.checkBody('username', 'Username is required').notEmpty();
req.checkBody('password', 'Password field is required').notEmpty();
req.checkBody('password2', 'Password do not match').equals(req.body.password);
// Check for Validation errors
var errors = req.validationErrors();
if(errors){
res.render('register', {
errors: errors,
name: name,
email: email,
username: username,
password: password,
password2: password2
});
}else {
var newUser = new User({
name: name,
email: email,
username: username,
password: password,
profileimage: profileImageName
});
// Create User
User.createUser(newUser, function(err, user){
if(err) throw err;
console.log(user);
});
// Success Message
req.flash('success', 'You are now registered and may log in');
res.location('/');
res.redirect('/');
}
});
And here is my register.jade code
extends layout
block content
h1 Register
p Please register using the form below
ul.errors
if errors
each error, i in errors
li.alert.alert-danger #{error.msg}
form(method='post', action='/users/register', enctype='multipart/form-data')
.form-group
label Name
input.form-control(name='name', type='text', placeholder='Enter Name')
.form-group
label Email
input.form-control(name='email', type='text', placeholder='Enter Email')
.form-group
label Username
input.form-control(name='username', type='text', placeholder='Enter Username')
.form-group
label Password
input.form-control(name='password', type='password', placeholder='Enter Password')
.form-group
label Confirm Password
input.form-control(name='password2', type='password', placeholder='Confirm Password')
.form-group
label Profile Image
input.form-control(name='profileimage', type='file')
input.btn.btn-default(name='submit', type='submit', value='Register')
Please any help would be so much appreciated... thanks
Body parser doesn't work with multipart form attribute set to form-data, but instead set to urlencoded which is this
<form action="/register" method="post" multipart="urlencoded"></form>
with that you should be good! Thank you all for your time. stay blessed
1) Use body parser and express-validator before router you used
2) if you use multipart/form-data then you use validator middleware after multer file upload strategy
this is work form me
var validator = function(req,res,next){
req.checkBody('name').notEmpty().withMessage('Name field is required');
}
router.post('/upload',multer.single('avatar'),validator,function(req,res,next){
//req.body
//req.file
both object available here
})
I have read all the related questions and responses and still can't fix this issue. Please see the code below and help me understand why terminal is throwing 'undefined is not a function'.
For a rundown of the functions:
The query section looks up SQL gets the users PW from DB. Parse results gets just the pw and eliminates the 'key' from the key value pair. Move pw function is there just as a buffer so that compare PW will not execute until we have retrieved the pw to compare with.
I have been stuck on this for a while, any help is much appreciated. To see the running app, go here...a working un/pw combo are user5 1234, but bc of the error it will look up username, password, verify that its a match (the compare pw and the look up pw functions actually do work and tell you if its a existing pw and un combo, but when i try and return done(user, null) to the passport login route, it crashes...
https://[redacted].com/
var express = require('express');
var router = express.Router();
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
var db = require('../database');
var returnedPw;
var flash = require('connect-flash');
var session = require('express-session');
var mysql = require('mysql');
var connection = mysql.createConnection({
host : 's',
user : 'n',
password : '',
database : 's'
});
//stripped credentioals
// Include User Model
var User = require('../models/user');
// Include Student Model
var Client = require('../models/client');
// Include Instructor Model
var Company = require('../models/company');
router.get('/signup', function(req, res, next) {
res.render('users/signup');
});
router.post('/signup', function(req, res, next){
// Get Form Values
console.log('starting post and making new user');
var first_name = req.body.first_name;
var last_name = req.body.last_name;
var street_address = req.body.street_address;
var city = req.body.city;
var state = req.body.state;
var zip = req.body.zip;
var email = req.body.email;
var username = req.body.username;
var password = req.body.password;
var password2 = req.body.password2;
var type = req.body.type;
// Form Field Validation
req.checkBody('first_name', 'First name field is required').notEmpty();
req.checkBody('last_name', 'Last name field is required').notEmpty();
req.checkBody('email', 'Email field is required').notEmpty();
req.checkBody('email', 'Email must be a valid email address').isEmail();
req.checkBody('username', 'Username field is required').notEmpty();
req.checkBody('password', 'Password field is required').notEmpty();
req.checkBody('password2', 'Passwords do not match').equals(req.body.password);
var errors = req.validationErrors();
if(errors){
res.render('users/signup', {
errors: errors,
first_name: first_name,
last_name: last_name,
street_address: street_address,
city: city,
state: state,
zip: zip,
email: email,
username: username,
password: password,
password2: password2
});
} else {
var newUser = new User({
email: email,
username:username,
password: password,
type: type
});
console.log('calling post to database file to receive new user:' + newUser)
// THIS IS WHERE WE ARE POSTING THE NEW USER TO THE DATABASE!!!
db.postUsers(newUser);
var newClient = new Client({
first_name: first_name,
last_name: last_name,
address: [{
street_address: street_address,
city: city,
state: state,
zip: zip
}],
email: email,
username:username
});
if(type == 'client'){
//User.saveClient(newUser, newClient, function(err, user){
// console.log('Client created');
///}); works but replacing w sql
} else {
var newCompany = new Company({
first_name: first_name,
last_name: last_name,
address: [{
street_address: street_address,
city: city,
state: state,
zip: zip
}],
email: email,
username:username
});
//works but replacing w sql
//User.saveCompany(newUser, newCompany, function(err, user){
// console.log('Company created');
//});
//sql save function
console.log('calling sql save..');
//db.postUsers(newUser, newClient);
}
req.flash('success','User added');
res.redirect('/');
}
});
<!--//// -USER AUTH SECTION- \\\\--!><!--//// -USER AUTH SECTION- \\\\--!><!--//// -USER AUTH SECTION- \\\\--!>
/*
passport.serializeUser(function(user, done) {
done(null, user._id);
});
passport.deserializeUser(function(id, done) {
User.getUserById(id, function (err, user) {
done(err, user);
});
}); */
passport.serializeUser(function(user, done) {
done(null, user);
});
passport.deserializeUser(function(user, done) {
done(null, user);
});
router.post('/login',passport.authenticate('local',{failureRedirect:'/', failureFlash:'Wrong Username or Password'}), function(req, res){
req.flash('success','You are now logged in');
var usertype = req.user.type;
res.redirect('/'/*+usertype+'s/classes' */);
});
passport.use(new LocalStrategy(
function(username, password, done ) {
console.log('in users the username is ' + username)
connection.query('SELECT password FROM t_user WHERE username = ?', username, function(err, user) {
parseResults(user, done);
});// end query
function parseResults(user, done) {
Object.keys(user)[0];
var key = Object.keys(user)[0];
user[key];
var storedPw = user[key];
for(var i in storedPw){
returnedPw = storedPw[i];
}
console.log('returnedPw is defined here ' +returnedPw);
movePw(returnedPw, done);
}// end function
var candidatePassword = password;
function movePw (returnedPw, done) {
if (returnedPw ) {
User.comparePassword(candidatePassword, returnedPw, function(err, isMatch) {
if (err) return done(err);
if(isMatch) {
//return done(null, user);
// req.flash('success','User Access Granted');
//console.log('go head')
user = username;
return done(null, user);
//done(null, user);
//notifyOuterScope();
//return true;
} else {
console.log('Invalid Password');
// Success Message
req.flash('failureFlash','User Access Denied. False Password');
return done(null, false, { message: 'Invalid password' });
}
});
}
else {console.log('return PW not defined')}
}
}// end outer function ?
));//end passport
// Log User Out
router.get('/logout', function(req, res){
req.logout();
// Success Message
req.flash('success', "You have logged out");
res.redirect('/');
});
function ensureAuthenticated(req, res, next) {
if (req.isAuthenticated()) {
return next();
}
res.redirect('/')
}
/* COMPARING PASSWORDS */
/* where are we returning the password from the user db profile?
bcrypt.hash('mypassword', 10, function(err, hash) {
if (err) { throw (err); }
bcrypt.compare('mypassword', hash, function(err, result) {
if (err) { throw (err); }
console.log(result);
});
});
*/
module.exports = router;
The code is a working example of using SQL and passport.js with node. I was having difficulty using the Local Strategy required for passport (using sql commands instead of mongodb commands that you see in most passport documentation), and it turns out the reason is because I wasn't passing the correct variables/ was also passing in unnecessary variables.
I corrected it above. Instead of using the User.FindOne Mongo db query in local strategy, this is an example of how to do the same username/ password querys using SQL, within passport local strategy. There isn't much documentation on using SQL and passport / node.