async authenticate(req, res, cb) {
    if (!cb) {
      // first call : get redirected to M$ servers
      const response = await this.strategy.getRequestToken();
      const requestToken = response.oauth_token;
      const requestTokenSecret = response.oauth_token_secret;
      const callbackConfirmed = response.oauth_callback_confirmed;
      if (callbackConfirmed) {
        // cache the token secret
        await this.yggdrasil.storageService.setCache({
          key: `token-${requestToken}`,
          body: requestTokenSecret,
          options: {
            ttl: 300
          }
        });

        return res.status(302).redirect(`https://api.twitter.com/oauth/authorize?oauth_token=${requestToken}`);
      }
      res
        .status(500)
        .json({
          status: 500,
          message: 'Internal Server Error'
        });
      this.yggdrasil.fire('log', 'error', 'Twitter Auth - getRequestToken : callback not confirmed');

      throw new Error('Callback not confirmed');
    }

    // second call :
    // Get the oauth_verifier query parameter
    const oauthVerifier = req.query.oauth_verifier;
    // Get the oauth_token query parameter.
    // It's the same as the request token from step 1
    const callbackToken = req.query.oauth_token;

    try {
      // Get the request token secret from cache
      const callbackTokenSecret = await this.yggdrasil.storageService.getCache(`token-${callbackToken}`);

      const accessInfos = await this.strategy.getAccessToken(callbackToken, callbackTokenSecret, oauthVerifier);

      const rawProfile = await request({
        method: 'GET',
        url: `https://api.twitter.com/1.1/users/show.json?user_id=${accessInfos.user_id}`,
        headers: {'Authorization': `Bearer ${this.bearer}`}
      });
      // lets pick the useful data
      let profile = ((
        {name, screen_name, location, profile_image_url_https, profile_banner_url}
      ) => (
        {name, screen_name, location, profile_image_url_https, profile_banner_url}
      ))(rawProfile.data);

      profile.provider = 'twitter';
      profile.id = rawProfile.data.id_str;
      return cb(profile);
    } catch (e) {
      this.yggdrasil.fire('log', 'error', 'Twitter OAuth', e);
      cb(null);
      throw e;
    }
  }
/**
   * 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) {
      const response = await this.strategy.getRequestToken();
      const requestToken = response.oauth_token;
      const requestTokenSecret = response.oauth_token_secret;
      const callbackConfirmed = response.oauth_callback_confirmed;
      if (callbackConfirmed) {
        await this.yggdrasil.storageService.setCache({
          key: `token-${requestToken}`,
          body: requestTokenSecret,
          options: {
            ttl: 300
          }
        });
        return res.status(302).redirect(`https://api.twitter.com/oauth/authorize?oauth_token=${requestToken}`);
      }
      res
        .status(500)
        .json({
          status: 500,
          message: 'Internal Server Error'
        });
      this.yggdrasil.fire('log', 'error', 'Twitter Auth - getRequestToken : callback not confirmed');
      throw new Error('Callback not confirmed');
    }
    const oauthVerifier = req.query.oauth_verifier;
    const callbackToken = req.query.oauth_token;
    try {
      const callbackTokenSecret = await this.yggdrasil.storageService.getCache(`token-${callbackToken}`);
      const accessInfos = await this.strategy.getAccessToken(callbackToken, callbackTokenSecret, oauthVerifier);
      const rawProfile = await request({
        method: 'GET',
        url: `https://api.twitter.com/1.1/users/show.json?user_id=${accessInfos.user_id}`,
        headers: {'Authorization': `Bearer ${this.bearer}`}
      });
      let profile = ((
        {name, screen_name, location, profile_image_url_https, profile_banner_url}
      ) => (
        {name, screen_name, location, profile_image_url_https, profile_banner_url}
      ))(rawProfile.data);
      profile.provider = 'twitter';
      profile.id = rawProfile.data.id_str;
      return cb(profile);
    } catch (e) {
      this.yggdrasil.fire('log', 'error', 'Twitter OAuth', e);
      cb(null);
      throw e;
    }
  }
async authenticate ( req , res , cb ) { if ( ! cb ) { const response = await this . strategy . getRequestToken ( ) ; const requestToken = response . oauth_token ; const requestTokenSecret = response . oauth_token_secret ; const callbackConfirmed = response . oauth_callback_confirmed ; if ( callbackConfirmed ) { await this . yggdrasil . storageService . setCache ( { key : ` ${ requestToken } ` , body : requestTokenSecret , options : { ttl : 300 } } ) ; return res . status ( 302 ) . redirect ( ` ${ requestToken } ` ) ; } res . status ( 500 ) . json ( { status : 500 , message : 'Internal Server Error' } ) ; this . yggdrasil . fire ( 'log' , 'error' , 'Twitter Auth - getRequestToken : callback not confirmed' ) ; throw new Error ( 'Callback not confirmed' ) ; } const oauthVerifier = req . query . oauth_verifier ; const callbackToken = req . query . oauth_token ; try { const callbackTokenSecret = await this . yggdrasil . storageService . getCache ( ` ${ callbackToken } ` ) ; const accessInfos = await this . strategy . getAccessToken ( callbackToken , callbackTokenSecret , oauthVerifier ) ; const rawProfile = await request ( { method : 'GET' , url : ` ${ accessInfos . user_id } ` , headers : { 'Authorization' : ` ${ this . bearer } ` } } ) ; let profile = ( ( { name , screen_name , location , profile_image_url_https , profile_banner_url } ) => ( { name , screen_name , location , profile_image_url_https , profile_banner_url } ) ) ( rawProfile . data ) ; profile . provider = 'twitter' ; profile . id = rawProfile . data . id_str ; return cb ( profile ) ; } catch ( e ) { this . yggdrasil . fire ( 'log' , 'error' , 'Twitter OAuth' , e ) ; cb ( null ) ; throw e ; } }
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 // cache the token secret // second call : // Get the oauth_verifier query parameter // Get the oauth_token query parameter. // It's the same as the request token from step 1 // Get the request token secret from cache // lets pick the useful data