javascriptnode.jsexpresspassport.jspassport-google-oauth

Getting erros using passport-google-oauth20 InternalOAuthError: Failed to fetch user profile and Cannot set headers after they are sent to the client


I'm using passport strategies for different socialMedia logins and getting the following two errors

  1. InternalOAuthError: Failed to fetch user profile
  2. Cannot set headers after they are sent to the client
    I have doubt there somewhere I have returned a callback or response so getting 2nd error but for 1st don't know reasons scope seems to be correct!

strategy code

passport.use(new GoogleStrategy({
  clientID: GOOGLE_CLIENT_ID,
  clientSecret: GOOGLE_SECRET_KEY,
  callbackURL: GOOGLE_CALLBACK_URL
}, async (acessToken, refreshToken, profile, done) => {
  await User.findOne({ email: profile._json.email }, async (err, user) => {
    if (err) {
      console.log("passport.config --> err", err);
     done(err, null);
    } else if (user) {
      if (user.socialType !== "GOOGLE" || user.socialType === null)
        done(`LOGIN_CREDENTIALS_WITH_${(user.socialType || "PASSWORD").toUpperCase()}`, false);
      else {
       done(null, user);
      }
    } else {
      // console.log(profile);
      const user = {
        email: profile._json.email,
        socialId: profile.id,
        socialType: "GOOGLE",
        firstName: profile.name.givenName,
        lastName: profile.name.familyName,
        isActive: profile._json.email_verified,
        isVerified: profile._json.email_verified,
        socialImageUrl: profile._json.picture,
        userType: "CUSTOMER"
      };
      const newUser = new User({ ...user });
      const newUserData = await newUser.save();
     done(null, newUserData);
    }
  });
}));

route code:

router.get('/auth/:socialType', customerCtrl.socialTypeLogin);

router.get('/auth/:socialType/callback', customerCtrl.socialTypeLoginCallback);

controller code:

const socialTypeLogin = async (req, res) => {
    await customerService.socialTypeLogin(req, res);
};

const socialTypeLoginCallback = async (req,res) => {
  await customerService.socialTypeLoginCallback(req,res);
};

service code:

const socialTypeLogin = async (req, res) => {
    try {
      const socialType = (req.params.socialType || '').toLowerCase();
      const GOOGLE_SCOPE = ['email', 'profile'];
      const FACEBOOK_SCOPE = ['email'];
      let scope = [];
      if (socialType === 'google') {
        scope = GOOGLE_SCOPE;
      } else if (socialType === 'facebook') {
        scope = FACEBOOK_SCOPE;
      }
      let oauthOptions = { scope: scope};
      const { returnUrl } = req.query;
      if(returnUrl && returnUrl.trim().length !== 0) {
        oauthOptions['state'] =JSON.stringify({ returnUrl: returnUrl });
      }
      passport.authenticate(socialType, oauthOptions)(req, res);
    }
    catch (error) {

    }
}

/**
 * @param {string} socialType
 */

const socialTypeLoginCallback = async (req, res) => {
  const socialType = (req.params.socialType || '').toLowerCase();
  // return new Promise((resolve, reject) => {
    try {
      passport.authenticate(socialType, async (err, user) => {
        let webappRedirectURL = WEBAPP_LOGIN_URL;
        try {
          const state = req.query.state; 
          if(state) {
            const stateObj = JSON.parse(state);
            webappRedirectURL = stateObj.returnUrl;
          }
        } catch (err1) {
          console.log("customer.service --> parsing error",err1);
        }
        if (err || !user) {
          console.log("customer.service --> !user",err);
          res.render('oauth-redirect', {
            webappRedirectURL: webappRedirectURL,
            success: false,
            error: err,
            timerCounter: 5,
            accessToken: undefined
          });
        }
        else {
          console.log("customer.service --> Generating Token",user.generateJWT());
          res.render('oauth-redirect', {
            webappRedirectURL: webappRedirectURL,
            success: true,
            timerCounter: 5,
            accessToken: user.generateJWT(),
            error: undefined
          });
        }
      })(req, res);
    } 
    catch (error) {
      console.log("customerService.js ==> socialTypeLoginCallback -->",error);
    }
};

Thanks for help in advance! I have doubt there somewhere I have returned a callback or response so getting 2nd error but for 1st don't know reasons scope seems to be correct!


Solution

  • In socialTypeLogin add line

    oauthOptions['session'] = false;