0

I am using mocha, chai and supertest to test my api's. I have the test for logging in a user working. I want to run a separate test to see if the user is logged in.

I am using express, express-session and passport on the server side to authenticate. I have code in my client and server to check if the user is logged in.

server - index.js


const express = require('express');
const bodyParser = require('body-parser');
const cors = require('cors');

const session = require('express-session');
const passport = require('passport');
const LocalStrategy = require('passport-local').Strategy;
const bcrypt = require('bcrypt');

require("dotenv").config();
const port = process.env.PORT;

const app = express()

// app.use(cors());
app.use(cors({
  origin: 'http://localhost:3000',
  credentials: true,
  allowedHeaders: ['Content-Type']
}));
app.use(bodyParser.json());
app.use(
  bodyParser.urlencoded({
    extended: true,
  })
);

app.set('trust proxy', 1);

// passport and session startup - start vvvv
const userQuery = require('./db/userQueries');

// configure passport LocalStrategy
passport.use(
  new LocalStrategy(
    {
      usernameField: 'email',
      passwordField: 'password'
    },
    async (username, password, done) => {
      const errMsg = 'Incorrect username or password';
      try {
        const user = await userQuery.findUserByEmail(username);
        // if did not find user
        if (!user) return done(null, false, { message: errMsg });
        // found user, try to match hashed password        
        const matchedPassword = await bcrypt.compare(password, user.password_hash);
        // if password hashes do not match
        if (!matchedPassword) return done(null, false, { message: errMsg });
        // password hashes match                   
        return done(null, user);
      } catch (err) {
        return done(err);
      }
    }
  )
);

// passport serializeUser/deserializeUser
passport.serializeUser((user, done) => {
  done(null, user.guid);
});
passport.deserializeUser( async (guid, done) => {  
  const user = await userQuery.findUserByGuid(guid); 
  return done(null, user);
});

// session configuration
// app.use(session) BEFORE app.use(passport....)

// NOTE: for local testing, set cookie: secure to false. 
// setting cookie: {secure: true} , the cookie will only be set over an 
// https connection, and not over an http connection
// https://stackoverflow.com/questions/71184167/why-setting-the-cookie-secure-to-true-in-express-session-allows-session-id-and-d
app.use(session({
  secret: process.env.SESSION_SECRET || 'not_so_secret',
  resave: true,
  cookie: {
    maxAge: 1000 * 60 * 60 * 24,
    secure: false,
    httpOnly: true,
    path: '/'
  },
  saveUninitialized: true  
}));

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

// passport and session startup - end ^^^^

// routes
const authRouter = require('./routes/auth');
app.use(`${baseUrl}/auth`, authRouter);

app.listen(port, () => {
  console.log(`Server started on port ${port}.`)
});

module.exports = app;

server - auth.js


const express = require('express');
const authRouter = express.Router();
const passport = require("passport");

authRouter.post('/login', (req, res, next) => {
  passport.authenticate('local', (err, theUser, failureDetails) => {
    if (err) {
      res.status(500).json({ message: "Something went wrong authenticating user" });
      return;
    }
    if (!theUser) {
      res.status(401).json(failureDetails);
      return;
    }
    // save user in session
    req.login(theUser, (err) => {
      if (err) {
        res.status(500).json({ message: "Session save went bad." });
        return;
      }
      res.setHeader('Access-Control-Allow-Credentials', 'true');
      res.status(200).json({ errors: false, user: theUser });
    });
  })(req, res, next);
});

function loggedIn(req, res, next) {
  if (req.isAuthenticated()) {
    next();
  } else {        
    res.status(401).send('not logged in');
  }
};

authRouter.get('/is_logged_in', loggedIn, (req, res) => {
  res.status(200).send("User logged in")
});

module.exports = authRouter;

client - app.js


    const response = await fetch('http://localhost:5000/auth/is_logged_in', {
      method: "GET", 
      headers: {
        'Accept': 'application/json',
        'Content-Type': 'application/json',            
      },           
      credentials: 'include'
    });   
    if (response.status === 200) {
    } else {
    }    


I have tried using .set() to set the credentials, but is is not working in the test

      it('confirm user is logged in', async function () {        
        const response = await request(app)          
          .get(`${baseUrl}/is_logged_in`)
          .set('Accept', 'application/json')
          .set('Content-Type', 'application/json')
          .set('credentials', 'include');          
        assert.equal(response.status, 200);
      });

John Kugelman
  • 349,597
  • 67
  • 533
  • 578

0 Answers0