async authenticate(req, res, cb) {
    if (!cb) {
      // first call : get redirected to M$ servers
      try {
        const redirectURL = await this.pca.getAuthCodeUrl(this.authCodeUrlParameters);
        return res.redirect(redirectURL);
      } catch (error) {
        res
          .status(500)
          .json({
            status: 500,
            message: 'Internal Server Error'
          });
        this.yggdrasil.fire('log', 'error', 'MSAUTH - get redirect url', error);
        throw error;
      }
    }

    // second call :
    const tokenRequest = {
      code: req.query.code,
      scopes: this.scopes,
      redirectUri: this.rootURL + '/callback' // why is this required again ????
    };

    let tokenResponse = {};

    try {
      tokenResponse = await this.pca.acquireTokenByCode(tokenRequest);
    } catch (error) {
      this.yggdrasil.fire('log', 'error', 'MSAUTH2', error);
      cb(null);
      throw error;
    }
    try {
      const profile = await request({
        method: 'GET',
        url: 'https://graph.microsoft.com/v1.0/me',
        headers: {'Authorization': `Bearer ${tokenResponse.accessToken}`}
      });
      profile.data.provider = 'microsoft';
      profile.data.email = tokenResponse.account.idTokenClaims.email;
      profile.data.family_name = tokenResponse.account.idTokenClaims.family_name;
      profile.data.given_name = tokenResponse.account.idTokenClaims.given_name;
      return cb(profile.data);
    } catch (error) {
      this.yggdrasil.fire('log', 'error', 'MSGraph', error);
      cb(null);
      throw error;
    }
  }
/**
   * Mimic the passport authenticate method
   *
   * This method is usually called 2 times :
   *  - the first time by the /api/auth/login/microsoft route to be redirected to the M$ server
   *  - the second time by the /api/auth/login/microsoft/callback route to get the user profile back
   *
   *  When the first call is made, the cb (callback function) is not set.
   *  The cb param is set only at the second call
   *
   * @param req
   * @param res
   * @param cb
   * @returns {Promise<void|never|Response>}
   */


When the first call is made, the cb (callback function) is not set.
The cb param is set only at the second call


When the first call is made the cb ( callback function ) is not set . The cb param is set only at the second call
async authenticate(req, res, cb) {
    if (!cb) {
      try {
        const redirectURL = await this.pca.getAuthCodeUrl(this.authCodeUrlParameters);
        return res.redirect(redirectURL);
      } catch (error) {
        res
          .status(500)
          .json({
            status: 500,
            message: 'Internal Server Error'
          });
        this.yggdrasil.fire('log', 'error', 'MSAUTH - get redirect url', error);
        throw error;
      }
    }
    const tokenRequest = {
      code: req.query.code,
      scopes: this.scopes,
      redirectUri: this.rootURL + '/callback' 
    };
    let tokenResponse = {};
    try {
      tokenResponse = await this.pca.acquireTokenByCode(tokenRequest);
    } catch (error) {
      this.yggdrasil.fire('log', 'error', 'MSAUTH2', error);
      cb(null);
      throw error;
    }
    try {
      const profile = await request({
        method: 'GET',
        url: 'https://graph.microsoft.com/v1.0/me',
        headers: {'Authorization': `Bearer ${tokenResponse.accessToken}`}
      });
      profile.data.provider = 'microsoft';
      profile.data.email = tokenResponse.account.idTokenClaims.email;
      profile.data.family_name = tokenResponse.account.idTokenClaims.family_name;
      profile.data.given_name = tokenResponse.account.idTokenClaims.given_name;
      return cb(profile.data);
    } catch (error) {
      this.yggdrasil.fire('log', 'error', 'MSGraph', error);
      cb(null);
      throw error;
    }
  }
async authenticate ( req , res , cb ) { if ( ! cb ) { try { const redirectURL = await this . pca . getAuthCodeUrl ( this . authCodeUrlParameters ) ; return res . redirect ( redirectURL ) ; } catch ( error ) { res . status ( 500 ) . json ( { status : 500 , message : 'Internal Server Error' } ) ; this . yggdrasil . fire ( 'log' , 'error' , 'MSAUTH - get redirect url' , error ) ; throw error ; } } const tokenRequest = { code : req . query . code , scopes : this . scopes , redirectUri : this . rootURL + '/callback' } ; let tokenResponse = { } ; try { tokenResponse = await this . pca . acquireTokenByCode ( tokenRequest ) ; } catch ( error ) { this . yggdrasil . fire ( 'log' , 'error' , 'MSAUTH2' , error ) ; cb ( null ) ; throw error ; } try { const profile = await request ( { method : 'GET' , url : 'https://graph.microsoft.com/v1.0/me' , headers : { 'Authorization' : ` ${ tokenResponse . accessToken } ` } } ) ; profile . data . provider = 'microsoft' ; profile . data . email = tokenResponse . account . idTokenClaims . email ; profile . data . family_name = tokenResponse . account . idTokenClaims . family_name ; profile . data . given_name = tokenResponse . account . idTokenClaims . given_name ; return cb ( profile . data ) ; } catch ( error ) { this . yggdrasil . fire ( 'log' , 'error' , 'MSGraph' , error ) ; cb ( null ) ; throw error ; } }
Mimic the passport authenticate method
 This method is usually called 2 times :
  - the first time by the /api/auth/login/microsoft route to be redirected to the M$ server
  - the second time by the /api/auth/login/microsoft/callback route to get the user profile back
Mimic the passport authenticate method This method is usually called 2 times : - the first time by the / api / auth / login / microsoft route to be redirected to the M$ server - the second time by the / api / auth / login / microsoft / callback route to get the user profile back
// first call : get redirected to M$ servers // second call : // why is this required again ????