I'm currently in the process of writing a "modular" REST API that uses JWT for authentication. It's been a stressful process, but I've been encountering issues and fixing them one by one. Sadly I've stumbled upon an issue I'm not exactly sure how to fix.
Basically, I have an auth endpoint where I make a POST request with new user information, but for some reason, I keep getting the error "Unhandled rejection Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client"
The way this endpoint works is that it calls a controller function called createUser which can be seen below:
'use strict'
const UserService = require('../../services/users')
const User = require('../../domain/user')
const TokenService = require('../../services/tokens')
const config = require("../../config/auth.config"); //secret key
const tokenService = new TokenService()
const userService = new UserService()
const mailService = require('../../services/mail')
class UserController {
createUser(req, res, next) {
console.log("Create user!")
console.log("User: " + JSON.stringify(req.body));
const user = new User(req.body)
userService.createNewUser(user).then(user => {
return tokenService.createToken({
firstName: user.firstName,
lastName: user.lastName,
email: user.email,
}, config.secret)
}).then(token => {
// who cares if it fails, we have a resend option
return mailService.sendActivationEmail(user.email, token)
}).then(() => {
res.status(201).send()
}).catch(err => res.status(500).send(err.message))
next();
}
activateUser(req, res, next) {
const token = req.query.token
tokenService.verifyToken(token, config.secret).then(user => {
if (!user || !user.email) {
throw new Error('Token not valid')
}
return userService.activateUser(user.email)
}).then(() => {
res.status(202).send({apiToken: token})
}).catch(err => {
res.status(500).send(err.message)
})
}
}
module.exports = UserController;
Then it calls a user service I made and then a token service which handles token creation, verification etc. With a bunch of logging statements, I've narrowed down the issue to the TokenService which contains a createToken function which is below:
'use strict'
const jwt = require('jsonwebtoken')
module.exports = (embeddedData, secretKey) => {
console.log('Embedded Data:' + JSON.stringify(embeddedData))
return Promise.resolve(jwt.sign(embeddedData, secretKey))
console.log("Token created.");
}
After the Embedded Data output which outputs the JSON: {"firstName":"John","lastName":"Smith","email":"johnsmith123@gmail.com"}
The "Cannot set headers after they are sent to the client" happens there, therefore "Token created" is not outputting
I have searched over StackOverflow but from what I'm seeing, I think I am doing everything right. Incase it helps, I'm defining my route as:
app.post("/api/auth/signup",
controller.createUser
);
I would appreciate any help, I've been scratching my head over this and am not sure what to do next.
Thanks!