MongooseError: Query.prototype.exec() no longer accepts a callback with passport.authenticate()

680 Views Asked by At

I am writing a simple register/login page with passportLocalMongoose. I am working on my register page for users, I am able to store all the data into mongodb once I click register button, but when I am trying to redirct to the authenticated page I am getting an error :

MongooseError: Query.prototype.exec() no longer accepts a callback

Here is my code

const bodyParser = require('body-parser');
const mongoose = require('mongoose');
const express = require('express')
const ejs = require("ejs");

const session = require('express-session');
const passport = require("passport");
const passportLocalMongoose = require("passport-local-mongoose");

const app = express()

app.use(bodyParser.urlencoded({ extended: true }))
app.set('view engine', 'ejs');
app.use(express.static("public"));



app.use(session({
  secret:'the s key',
  resave:false,
  saveUninitialized:false
}));

app.use(passport.initialize());
app.use(passport.session());



mongoose.connect("mongodb://0.0.0.0:27017/userDB", {useNewUrlParser: true});

const userSchema = new mongoose.Schema({
  username:String,
  password:String,
  tbd:String
});

//hash and salt psw and save users to db
userSchema.plugin(passportLocalMongoose);

const User = mongoose.model('User', userSchema);

passport.use(User.createStrategy());
// passport.use(new LocalStrategy({
//     usernameField: 'email',
//   },User.authenticate()));

passport.serializeUser(User.serializeUser());
passport.deserializeUser(User.deserializeUser());



app.get('/test', function(req,res){
  res.render('test');
});

app.get('/login', function(req,res){
  res.render('login');
});

app.get('/register',function(req,res){
  res.render('register');
});

app.get('/',function(req,res){
  res.redirect('login');
});

app.get("/mainpage",function(req,res){
  if(req.isAuthenticated()){
    console.log(req.isAuthenticated());
    res.render('/mainpage');
  }else{
    console.log(req.isAuthenticated());
    res.redirect('login');
  }
});

app.get('/logout',function(req,res){
  req.logout();
  res.redirct('/login')
})


app.post('/login',function(req,res){
  const user = new User({
    username:req.body.username,
    password:req.body.psw
  });

  req.login(user,function(err){
    if (err) {
      console.log(err);
    }else{
      passort.authenticate("local")(req, res, function(){
        res.redirct("/mainpage")
      })
    }

  });
});

app.post("/register", function(req, res){
  User.register({username: req.body.username}, req.body.password, function(err, user){
    if (err) {
      console.log(err);
      res.redirect("/register");
    } else {
        passport.authenticate('local').then(()=> {
        res.redirect("/mainpage");
    })
      }
  });

});

app.listen(3000, function() {
  console.log("Server started on port 3000");
});
1

There are 1 best solutions below

5
Imran Azim On

Your passport authenticate will be like the following and try again.

passport.authenticate('local', function (err, user, info) {
    if (err) {
        return res.send({'success': false, message: err});
        // return res.redirect('your_route');
    }
    // Generate a JSON response reflecting authentication status
    if (!user) {
        return res.send({'success': false, message: 'Invalid 
        Credentials'});
        // return res.redirect('your_route');
    }
    req.login(user, loginErr => {
        if (loginErr) {
            return res.send({'success': false, message: 'Invalid 
            Credentials'});
            // return res.redirect('your_route');
        }
        return res.status(200).send({
         success: true,
         message: 'User logged in successfully',
         user: user
        })
        // return res.redirect("/mainpage");
    })
 })

On thing to be noted that make sure you have created the strategy of local in app.js main. Place the following code in app.js:

//serialize
passport.serializeUser(function (user, done) {
  done(null, user)
})
// deserialize
passport.deserializeUser(function (user, done) {
  if (user) {
    done(null, user)
  } else {
    done(new Error('User was not found: ' + user.username, null))
  }
})
// authenticate admin user 
passport.use('local', new LocalStrategy({ usernameField: 'username' }, (username, password, done) => {
  User.findOne({
    where: { username: username }
  }).then((user) => {
    if (!user) {
      return done(null, false, { message: `Username ${username} was not found.` });
    }
    user.comparePassword(password, (err, isMatch) => {
      if (err) {
        return done(null, false, {message: err});
      }
      if (isMatch) {
        return done(null, user);
      } else if(!isMatch) {
        return done(null, false, {message: 'Your password is invalid.'});
      }
    });
  });
}));

And Make sure to send the field username and password from in request from frontend form:

<form action="/login" method="POST" id="login_form">
  <input type="text" name="username" id="username" placeholder="Username">
  <input type="password" name="password" id="password" placeholder="Password">
  <button type="submit" class="btn">Login</button>
</form>

Try this, I hope this help.