I’m going crazy with nodejs. I’m trying to realize the backend for a simple user management webapp powered by NodeJS, using Passport-Local and Sequelize libraries. Right now I just designed the user model. The main problem I have is that the signup process gives me an error: it looks like that I’m working on an undefined object. Could please someone help me in figuring out what’s going on?
Here is my code (merged with some solutions I found on internet – obviously nothing works, according to Murphy’s laws).
Could please Javascript programmers forgive me if the code is not good. My excuse is that it is my first programming attempt in Javascript, I MUST do it for a project and last (excuse) but not least I grew up with C and microchips.
ERROR:
TypeError: Cannot read property ‘findOne’ of undefined at Strategy._verify (/home/me/Documents/cerbero/config/passport.js:21:17)
app.js
var app = express(); //blabla favicon stuff app.use(bodyParser.urlencoded({ extended: true })); app.use(bodyParser.json()); app.use(cookieParser()); app.use(express.static(path.join(__dirname, 'public'))); app.use(session({ secret:'holaholaholaholaholaholahola', resave:true, saveUninitialized:true })); app.use(passport.initialize()); app.use(passport.session()); app.use(flash()); app.set('views', path.join(__dirname, 'views')); app.set('view engine', 'pug'); var models = require("./models") require('./config/passport.js')(passport, models.usermodel); app.use('/', index); app.use('/user', require('./routes/users')(passport)); models.sequelize.sync().then(function(){ console.log("Database connected"); }).catch(function(err) { console.log(err, "Somenthing went wrong with the dbdbdb"); }); //blabla listening stuff module.exports = app;
models/usermodel.js
module.exports = function(sequelize, Sequelize) { var User = sequelize.define('user', { id: { autoIncrement: true, primaryKey: true, type: Sequelize.INTEGER }, username: { type: Sequelize.TEXT }, public_key: { type: Sequelize.TEXT }, email: { type: Sequelize.STRING, validate: { isEmail: true } }, password: { type: Sequelize.STRING, allowNull: false }, last_login: { type: Sequelize.DATE }, }); return User; }
routes/users.js
var express = require('express'); module.exports = function(passport, user) { var router = express.Router(); //blablabla other routes router.get('/signup', function(req,res,next) { res.render('signup', {message: req.flash('signupMessage')}); }); router.post('/signup', passport.authenticate('local-signup', { successRedirect: '/user/dashboard', failureRedirect: '/user/signup'} )); router.post('/login', passport.authenticate('local'), function(req, res) { res.redirect('/'); }); return router; }; function isLogged(req, res, next) { if (req.isAuthenticated()) return next(); res.redirect('/'); };
EDIT I forgot passport strategy. passport.js
var bCrypt = require('bcrypt-nodejs'); module.exports = function(passport, user) { var User = user; var LocalStrategy = require('passport-local').Strategy; console.log('debug: sono nella routine'); passport.use('local-signup', new LocalStrategy( { usernameField: 'email', passwordField: 'password', passReqToCallback: true }, function(req, email, password, done) { User.findOne({ where: { email: email } }).then(function(user) { if (user) { return done(null, false, {message: req.flash('email already taken')}); console.log('mail already taken'); } else { var pass = generateHash(password); var data = { email: email, password: pass, username: req.body.username, public_key: '0', last_login: null }; User.create(data).then(function(newUser, created) { if (!newUser) { return done(null, false); } if (newUser) { return done(null, newUser, {message: req.flash('tappost')}); } next(); }); } }); } )); passport.deserializeUser(function(id, done) { User.findById(id).then(function(user) { if (user) { done(null, user.get()); } else { done(user.errors, null); } }); }); passport.serializeUser(function(user,done) { done(null, user.id); }); var generateHash = function(password) { return bCrypt.hashSync(password, bCrypt.genSaltSync(8), null); };
Advertisement
Answer
Problem solved. “Just” changed how to reference the model in passport.js as follow
var User = user;
had to rewritten as
var User = db.user;
Here the definitive passport strategy file
const db = require('./../models/'); var bCrypt = require('bcrypt-nodejs'); module.exports = function(passport) { var User = db.user; var LocalStrategy = require('passport-local').Strategy; passport.use('local-signup', new LocalStrategy( { usernameField: 'email', passwordField: 'password', passReqToCallback: true }, function(req, email, password, done) { var generateHash = function(password) { return bCrypt.hashSync(password, bCrypt.genSaltSync(8), null); }; User.findOne({ where: { email: email } }).then(function(user) { if (user) { return done(null, false, {message: req.flash('email already taken')}); console.log('mail already taken'); } else { var pass = generateHash(password); var data = { email: email, password: pass, username: req.body.username, public_key: '0', last_login: null }; User.create(data).then(function(newUser, created) { if (!newUser) { return done(null, false); } if (newUser) { return done(null, newUser, {message: req.flash('tappost')}); } }); } }).catch(function(err) { console.log(err); }); } )); passport.serializeUser(function(user, done) { done(null, user.id); }); passport.deserializeUser(function(id, done) { User.findById(id).then(function(user){ done(null, user); }).catch(function(e){ done(e, false); }); }); }