'Node passport - Handle not returning profile/session with Google Strategy

I'm doing OAuth with passports Google strategy, where I check in the strategy if the user is trying to login or register for the first time.

In the case where for example a user that already has an account tries to register again I don't want to send back a session to the user, instead I simply want to redirect the to some page in the client and alert them that they are already registered.

What I'm currently trying to do is to run done(null, false) if the case is that the user is registered and tries to register again. What I would expect is that it would fail, then go to the specified failureRedirect and redirect the user. Instead it returns these error messages: InternalOAuthError: Failed to fetch user profile and Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client

How do you solve this and handle not returning a session to the user in the callback?

google.router.js

const googleRouter = require("express").Router();
var passport = require("passport");

const CLIENT_URL = "http://localhost:3000/";

// login endpoint
googleRouter.get(
  "/google",
  passport.authenticate("google", {
    scope: ["profile", "email"],
    successRedirect: '/auth/login/success',
    failureRedirect: '/auth/failure',
    state: "login",
  })
);

// register endpoint
googleRouter.get(
  "/register/google",
  passport.authenticate("google", {
    scope: ["profile", "email"],
    successRedirect: '/auth/login/success',
    failureRedirect: '/auth/failure',
    state: "register",
  })
);

// login/register callback endpoint
googleRouter.get(
  "/google/callback",
  passport.authenticate("google", {
    successRedirect: '/login/success',
    failureRedirect: "/auth/failure",
    session: true,
  }),
  (req, res) => {
    res.redirect(CLIENT_URL);
  }
);

module.exports = googleRouter;

auth.router.js

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

const CLIENT_URL = "http://localhost:3000/";

authRouter.get("/auth/failure", (req, res) => {
  res.status(401).json({
    success: false,
    message: "failure",
  }).redirect(CLIENT_URL);
});

module.exports = authRouter;

passport.js

const handleAuthenticationMethod = async (method, userData, provider) => {
  if (method === "login") {
    const userExists = await validateEmail(userData.emails[0].value);
    //check if user is valid
    if (userExists) {
      return true // return user session
    } else {
      return false;
    }
  }
  else if (method === "register") {
    const userExists = await validateEmail(userData.emails[0].value); 
    if (!userExists){
      //add user to database
      const formattedUser = formatUserData(userData, provider);
      const user = new User(formattedUser);
      await user.save();

      return true; //return user session
    }
    //if user already exists in database
    return false;
  }
}



passport.use(
  new GoogleStrategy(
    {
      clientID: GOOGLE_CLIENT_ID,
      clientSecret: GOOGLE_CLIENT_SECRET,
      callbackURL: "/auth/google/callback",
      passReqToCallback: true,
    },
    async function (req, accessToken, refreshToken, profile, done) {
      const validAuth = await handleAuthenticationMethod(req.query.state, profile, "google")
      if (validAuth){
        done(null, profile);
      }
      else{
        done(null, false);
      }
    }
  )
);


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source