I am trying to write a unit-test for the authentication route of my web application. For some reason, it times out. What is more, the test user is not created in the database. What am I doing wrong? Should I be specifying the database connection as well?
Here is the code of the test:
var user;
var mongoose = require("mongoose");
var userSchema = require("../../models/user.js");
var User = mongoose.model("User", userSchema);
var request = require("supertest");
var server = request.agent("http://localhost:3000");
describe('User', function () {
beforeEach(function(done) {
user = new User({
email : "user#user.com",
firstName: "Full Name",
lastName : "Last Name",
password : "pass11"
});
user.save(done)
});
describe('Login test', function () {
it('should redirect to /', function (done) {
agent
.post('/login')
.field('email', 'user#user.com')
.field('password', 'pass11')
.expect('Location','/')
.end(done)
})
afterEach(function(done) {
User.remove().exec();
return done();
});
});
})
routes/index.js
//module.exports = router;
var express = require('express');
var router = express.Router();
module.exports = function(passport){
var isAuthenticated = function (req, res, next) {
// if user is authenticated in the session, call the next() to call the next request handler
// Passport adds this method to request object. A middleware is allowed to add properties to
// request and response objects
if (req.isAuthenticated()){
//console.log(next());
return next();
}
// if the user is not authenticated then redirect him to the login page
res.redirect('/login');
}
/* GET login page. */
router.get('/login', function(req, res) {
// Display the Login page with any flash message, if any
res.render('login', { message: req.flash('message') });
});
/* Handle Login POST */
router.post('/login', passport.authenticate('login', {
successRedirect: '/',
failureRedirect: '/login',
failureFlash : true
}));
/* GET Registration Page */
router.get('/signup', function(req, res){
res.render('register',{message: req.flash('message')});
});
/* Handle Registration POST */
router.post('/signup', passport.authenticate('signup', {
successRedirect: '/',
failureRedirect: '/signup',
failureFlash : true
}));
/* GET Home Page when logged in */
router.get('/', isAuthenticated, function(req, res){
res.render('index', { user: req.user });
});
router.get('/user', function(req, res) {
var data = {
firstName: req.user.firstName,
lastName: req.user.lastName,
email: req.user.email,
/* ... */
};
res.send([
data
]);
});
/* Handle Logout */
router.get('/signout', function(req, res) {
req.logout();
res.redirect('/login');
});
return router;
}
Related
i'm using a localhost to test the passport-facebook authentication, i've been trying to implement the Auth and im getting the error mentioned above i've reviewed similar questions but none seem to help me, i've changed my dns address but to no avail,
this is my passport.js code for facebook authentication
const mongoose = require("mongoose");
const FacebookStrategy = require('passport-facebook').Strategy;
const passport = require('passport');
const User = module.exports = mongoose.model('User', facebookSchema)
var facebookSchema = mongoose.Schema
module.exports = function (_passport) {}
//serialize the user for the session
passport.serializeUser(function (user, done) {
done(null, user.id);
});
//deserialize the user
passport.deserializeUser(function (id, done) {
User.findById(id, function (err, user) {
done(err, user);
});
});
passport.use('facebook', new FacebookStrategy({
clientID: 'XXXXXXXXXX',
clientSecret: 'YYYYYYYYYYYYYYY',
callbackURL: " http://localhost:3000/auth/facebook/callback",
enableProof: true,
profileFields: ['id', 'displayName', 'photos', 'email']
},
function (accessToken, refreshToken, profile, done)
{ let newUser = new User();
// set the user's facebook credentials
newUser.facebook.email = profile.emails[0].value,
newUser.facebook.fullName = profile.displayName,
User.findOne({email:newUser.facebook.email }, function(err, user) {
if(!user) {
newUser.save(function(err, newUser) {
if(err) return done(err);
done(null,newUser);
});
} else {
done(null, user);
}
});
}
));
this is my index.js code for initiallizing app
const rfc = require('rfc-3986');
const express = require('express');
const bodyParser = require('body-parser');
var routes = require('./routes/routes'); //importing route
require('./models/userModel')
app = express();
port = 3000;
require("./config/db"); app.get('/success', (req, res) => res.send("You have successfully logged in"));
app.get('/error', (req, res) => res.send("error logging in"));
const passport = require("passport");
app.use(passport.initialize());
app.use(passport.session());
require('./config/passport')(passport);
app.set(rfc)
routes(app, passport);
app.set('view engine', 'ejs')
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({extended:true}))
app.listen(port,()=>{
console.log('server listening on localhost:' + port)
});
and this is my routes.js for app routing
app.get('/auth/facebook',
passport.authenticate('facebook', {scope:"email"}));
app.get('/auth/facebook/callback',
passport.authenticate('facebook', { failureRedirect: '/login' }),
function(req, res) {
// Successful authentication, redirect home.
res.redirect('/success');`module.exports = function(app, passport) {
app.get('/auth/facebook',
passport.authenticate('facebook', {scope:"email"}));
app.get('/auth/facebook/callback',
passport.authenticate('facebook', { failureRedirect: '/login' }),
function(req, res) {
// Successful authentication, redirect home.
res.redirect('/success');
});
}
});
}
this is the error i get on browser
this is the same error on terminal
How can I set in the authController file that I am logged in to return a user object to me?
I'm trying to do it this way to set res.json (req.body) in the userControllerer file inexports.register, but this probably returns the user when it is not known yet whether he is logged in? And my point is that, as in authController is success, it returns the object of the logged in user to me.
Routes/index.js
const express = require('express');
const router = express.Router();
const userController = require('../controllers/userController');
const authController = require('../controllers/authController');
router.get('/register', userController.registerForm);
router.post('/login', authController.login);
router.post('/register',
userController.validateRegister,
userController.register
authController.login
);
module.exports = router;
Controllers/userController.js
const mongoose = require('mongoose');
const User = mongoose.model('User');
exports.registerForm = (req, res) => {
res.json(req.body);
};
exports.register = async (req, res, next) => {
const newUser = new User({ email: req.body.email, name: req.body.name })
await User.register(newUser, req.body.password);
next()
}
Controllers/authController.js
const passport = require('passport');
exports.login = passport.authenticate('local', {
failureRedirect: '/login',
successRedirect: '/'
})
use the following implementation:
Routes/index.js
router.post('/login',
passport.authenticate('local'),
function(req, res) {
// If this function gets called, authentication was successful.
// `req.user` contains the authenticated user.
res.send(req.user);
});
I am trying to flash the message "Welcome back "username here" " to a user once they have successuly logged in to the website.
The problem is that logging in with passport is not a regular request and response, the authentication happens as an argument to the post request. Below you can find my code:
var express = require("express");
var router = express.Router();
var user = require("../models/user");
var passport = require("passport");
router.get('/register', (req,res) =>{
res.render('register');
});
router.post('/register', (req,res) =>{
user.register(
new user({username: req.body.username}),
req.body.password,
(err, newUser) => {
if(err){
req.flash("error", err.message);
return res.redirect("/register");
}
passport.authenticate("local")(req, res, function(){
req.flash("success", "Successfully registered, welcome "+user.username.charAt(0).toUpperCase() + user.username.slice(1)+"!");
res.redirect("/");
});
}
);
});
router.get('/login', (req,res) =>{
res.render('login');
});
router.post('/login', passport.authenticate("local",{
successRedirect: "/",
failureRedirect: "/login",
failureFlash: true,
successFlash: 'Welcome back!'//HERE IS WHERE I AM INTERESTED
}), (req,res) =>{
});
router.get('/logout', (req,res) =>{
req.logout();
req.flash("success", "Successfully Logged Out")
res.redirect("/");
});
module.exports = router;
In the second argument to router.post, call passport.authenticate to handle the failureRedirect and failureFlash message. Then, for the third argument, write your callback function with req and res. In the body of this function is where you'll handle the "success" flash message and you'll have access to your username on the request object. And then you can do your res.redirect.
router.post(
"/login",
passport.authenticate("local", {
failureRedirect: "/login",
failureFlash: true
}),
(req,res) => {
req.flash("success", "Welcome back!"//add your username variable here);
res.redirect("/home");
});
I'm using Cloud 9 to setup a basic social media website and I am having trouble with registration and authentication of users. I'm using Node.js, express and passport for authentication, and mongoDB as a database.
// PASSPORT Setup //
app.use(require("express-session")({
secret: "I am the best",
resave: false,
saveUninitialized: false
}));
app.use(passport.initialize());
app.use(passport.session());
passport.use(new LocalStrategy(User.authenticate()));
passport.serializeUser(User.serializeUser());
passport.deserializeUser(User.deserializeUser());
// INDEX Page
app.get("/", function(req, res) {
res.render("landing-page");
});
// REGISTER NEW
app.get("/register", function(req, res) {
res.render("user/register");
});
// REGISTER CREATE
app.post("/register", function(req, res) {
var user = req.body.user;
var newUser = new User({
username: user.email,
firstName: user.firstName,
lastName: user.lastName,
});
User.register(newUser, user.password, function(err, user) {
if(err) {
console.log(err);
return res.render("user/register");
}
passport.authenticate("local")(req, res, function() {
res.redirect("/");
});
});
});
// Login routes
app.get("/login", function(req, res) {
res.render("login");
});
app.post("/login", passport.authenticate("local", {
successRedirect: "/",
failureRedirect: "/login"
}) , function(req, res) {
});
// Logout route
app.get("/logout", function(req, res) {
req.logout();
res.redirect("/");
});
However whenever I run this, when I sign up a new user, it gives me a webpage with just "Bad Request", however the user is created in the database.
Look at this answer; the bad request is not a problem with your passport method: that indicates the request you try to make is not correct:
Did you set the head at: Content-Type: application-json?
Also update the bodyParser to the last version. This solved a similar problem I had.
Following the tutorial here
Auth.js
var passport = require("passport"),
LocalStrategy = require("passport-local").Strategy;
passport.use(new LocalStrategy(
function(username, password, done){
console.log("----", username, password, "----"); //this works fine, get the proper values here.
if(username === "admin" && password === "sw") {
return done(null, {username: "admin"});
}
return done(null, false);
}
));
passport.serializeUser(function(user, done){
done(null, user.username);
});
passport.deserializeUser(function(username, done){
done(null, {username: username});
});
module.exports = passport;
app.js (the relevant bits)
var passport = require("./auth")
var users = require('./routes/users');
.
.
.
app.use('/users', users);
app.post('/', passport.authenticate("local", {
failureRedirect: "/",
successRedirect: "/users"
}));
user route
var express = require('express');
var router = express.Router();
/* GET users listing. */
router.get('/', function (req, res, next) {
console.log(req.user);
res.render('users', {
title: 'Routed !'
});
});
module.exports = router;
Most of the code works fine, it posts and routes correctly, but, req.user is undefined in the users route, and I'm not able to figure out why.