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);
});