src/middlewares.js
// req.auth - the Auth for this request
req.auth - the Auth for this request
req . auth - the Auth for this request
function handleParseHeaders(req, res, next) {
  var mountPathLength = req.originalUrl.length - req.url.length;
  var mountPath = req.originalUrl.slice(0, mountPathLength);
  var mount = req.protocol + '://' + req.get('host') + mountPath;
  var info = {
    appId: req.get('X-Parse-Application-Id'),
    sessionToken: req.get('X-Parse-Session-Token'),
    masterKey: req.get('X-Parse-Master-Key'),
    installationId: req.get('X-Parse-Installation-Id'),
    clientKey: req.get('X-Parse-Client-Key'),
    javascriptKey: req.get('X-Parse-Javascript-Key'),
    dotNetKey: req.get('X-Parse-Windows-Key'),
    restAPIKey: req.get('X-Parse-REST-API-Key'),
    clientVersion: req.get('X-Parse-Client-Version')
  };
  var basicAuth = httpAuth(req);
  if (basicAuth) {
    var basicAuthAppId = basicAuth.appId;
    if (AppCache.get(basicAuthAppId)) {
      info.appId = basicAuthAppId;
      info.masterKey = basicAuth.masterKey || info.masterKey;
      info.javascriptKey = basicAuth.javascriptKey || info.javascriptKey;
    }
  }
  if (req.body) {
    delete req.body._noBody;
  }
  var fileViaJSON = false;
  if (!info.appId || !AppCache.get(info.appId)) {
    if (req.body instanceof Buffer) {
      req.body = JSON.parse(req.body);
      fileViaJSON = true;
    }
    if (req.body) {
      delete req.body._RevocableSession;
    }
    if (req.body &&
      req.body._ApplicationId &&
      AppCache.get(req.body._ApplicationId) &&
      (!info.masterKey || AppCache.get(req.body._ApplicationId).masterKey === info.masterKey)
    ) {
      info.appId = req.body._ApplicationId;
      info.javascriptKey = req.body._JavaScriptKey || '';
      delete req.body._ApplicationId;
      delete req.body._JavaScriptKey;
      if (req.body._ClientVersion) {
        info.clientVersion = req.body._ClientVersion;
        delete req.body._ClientVersion;
      }
      if (req.body._InstallationId) {
        info.installationId = req.body._InstallationId;
        delete req.body._InstallationId;
      }
      if (req.body._SessionToken) {
        info.sessionToken = req.body._SessionToken;
        delete req.body._SessionToken;
      }
      if (req.body._MasterKey) {
        info.masterKey = req.body._MasterKey;
        delete req.body._MasterKey;
      }
      if (req.body._ContentType) {
        req.headers['content-type'] = req.body._ContentType;
        delete req.body._ContentType;
      }
    } else {
      return invalidRequest(req, res);
    }
  }
  if (info.clientVersion) {
    info.clientSDK = ClientSDK.fromString(info.clientVersion);
  }
  if (fileViaJSON) {
    var base64 = req.body.base64;
    req.body = new Buffer(base64, 'base64');
  }
  info.app = AppCache.get(info.appId);
  req.config = new Config(info.appId, mount);
  req.info = info;
  var isMaster = (info.masterKey === req.config.masterKey);
  if (isMaster) {
    req.auth = new auth.Auth({ config: req.config, installationId: info.installationId, isMaster: true });
    next();
    return;
  }
  let keys = ["clientKey", "javascriptKey", "dotNetKey", "restAPIKey"];
  var keyMismatch = keys.reduce(function(mismatch, key){
    if (req.config[key] && info[key] !== req.config[key]) {
      mismatch++;
    }
    return mismatch;
  }, 0);
  if (keyMismatch == keys.length) {
    return invalidRequest(req, res);
  }
  if (req.url == "/login") {
    delete info.sessionToken;
  }
  if (!info.sessionToken) {
    req.auth = new auth.Auth({ config: req.config, installationId: info.installationId, isMaster: false });
    next();
    return;
  }
  return Promise.resolve().then(() => {
    if (info.sessionToken && 
        req.url === '/upgradeToRevocableSession' && 
        info.sessionToken.indexOf('r:') != 0) {
        return auth.getAuthForLegacySessionToken({ config: req.config, installationId: info.installationId, sessionToken: info.sessionToken })
    } else {
        return auth.getAuthForSessionToken({ config: req.config, installationId: info.installationId, sessionToken: info.sessionToken })
    }
  }).then((auth) => {
      if (auth) {
        req.auth = auth;
        next();
      }
    })
    .catch((error) => {
      if(error instanceof Parse.Error) {
        next(error);
        return;
      }
      else {
        log.error('error getting auth for sessionToken', error);
        throw new Parse.Error(Parse.Error.UNKNOWN_ERROR, error);
      }
    });
}
function handleParseHeaders ( req , res , next ) { var mountPathLength = req . originalUrl . length - req . url . length ; var mountPath = req . originalUrl . slice ( 0 , mountPathLength ) ; var mount = req . protocol + '://' + req . get ( 'host' ) + mountPath ; var info = { appId : req . get ( 'X-Parse-Application-Id' ) , sessionToken : req . get ( 'X-Parse-Session-Token' ) , masterKey : req . get ( 'X-Parse-Master-Key' ) , installationId : req . get ( 'X-Parse-Installation-Id' ) , clientKey : req . get ( 'X-Parse-Client-Key' ) , javascriptKey : req . get ( 'X-Parse-Javascript-Key' ) , dotNetKey : req . get ( 'X-Parse-Windows-Key' ) , restAPIKey : req . get ( 'X-Parse-REST-API-Key' ) , clientVersion : req . get ( 'X-Parse-Client-Version' ) } ; var basicAuth = httpAuth ( req ) ; if ( basicAuth ) { var basicAuthAppId = basicAuth . appId ; if ( AppCache . get ( basicAuthAppId ) ) { info . appId = basicAuthAppId ; info . masterKey = basicAuth . masterKey || info . masterKey ; info . javascriptKey = basicAuth . javascriptKey || info . javascriptKey ; } } if ( req . body ) { delete req . body . _noBody ; } var fileViaJSON = false ; if ( ! info . appId || ! AppCache . get ( info . appId ) ) { if ( req . body instanceof Buffer ) { req . body = JSON . parse ( req . body ) ; fileViaJSON = true ; } if ( req . body ) { delete req . body . _RevocableSession ; } if ( req . body && req . body . _ApplicationId && AppCache . get ( req . body . _ApplicationId ) && ( ! info . masterKey || AppCache . get ( req . body . _ApplicationId ) . masterKey === info . masterKey ) ) { info . appId = req . body . _ApplicationId ; info . javascriptKey = req . body . _JavaScriptKey || '' ; delete req . body . _ApplicationId ; delete req . body . _JavaScriptKey ; if ( req . body . _ClientVersion ) { info . clientVersion = req . body . _ClientVersion ; delete req . body . _ClientVersion ; } if ( req . body . _InstallationId ) { info . installationId = req . body . _InstallationId ; delete req . body . _InstallationId ; } if ( req . body . _SessionToken ) { info . sessionToken = req . body . _SessionToken ; delete req . body . _SessionToken ; } if ( req . body . _MasterKey ) { info . masterKey = req . body . _MasterKey ; delete req . body . _MasterKey ; } if ( req . body . _ContentType ) { req . headers [ 'content-type' ] = req . body . _ContentType ; delete req . body . _ContentType ; } } else { return invalidRequest ( req , res ) ; } } if ( info . clientVersion ) { info . clientSDK = ClientSDK . fromString ( info . clientVersion ) ; } if ( fileViaJSON ) { var base64 = req . body . base64 ; req . body = new Buffer ( base64 , 'base64' ) ; } info . app = AppCache . get ( info . appId ) ; req . config = new Config ( info . appId , mount ) ; req . info = info ; var isMaster = ( info . masterKey === req . config . masterKey ) ; if ( isMaster ) { req . auth = new auth . Auth ( { config : req . config , installationId : info . installationId , isMaster : true } ) ; next ( ) ; return ; } let keys = [ "clientKey" , "javascriptKey" , "dotNetKey" , "restAPIKey" ] ; var keyMismatch = keys . reduce ( function ( mismatch , key ) { if ( req . config [ key ] && info [ key ] !== req . config [ key ] ) { mismatch ++ ; } return mismatch ; } , 0 ) ; if ( keyMismatch == keys . length ) { return invalidRequest ( req , res ) ; } if ( req . url == "/login" ) { delete info . sessionToken ; } if ( ! info . sessionToken ) { req . auth = new auth . Auth ( { config : req . config , installationId : info . installationId , isMaster : false } ) ; next ( ) ; return ; } return Promise . resolve ( ) . then ( ( ) => if ( info . sessionToken && req . url === '/upgradeToRevocableSession' && info . sessionToken . indexOf ( 'r:' ) != 0 ) { return auth . getAuthForLegacySessionToken ( { config : req . config , installationId : info . installationId , sessionToken : info . sessionToken } ) } else { return auth . getAuthForSessionToken ( { config : req . config , installationId : info . installationId , sessionToken : info . sessionToken } ) } } ) . then ( ( auth ) => { if ( auth ) { req . auth = auth ; next ( ) ; } } ) . catch ( ( error ) => { if ( error instanceof Parse . Error ) { next ( error ) ; return ; } else { log . error ( 'error getting auth for sessionToken' , error ) ; throw new Parse . Error ( Parse . Error . UNKNOWN_ERROR , error ) ; } } ) ; }
req.auth - the Auth for this request
req . auth - the Auth for this request
// Unity SDK sends a _noBody key which needs to be removed. // Unclear at this point if action needs to be taken. // See if we can find the app id on the body. // The only chance to find the app id is if this is a file // upload that actually is a JSON body. So try to parse it. // TODO: test that the REST API formats generated by the other // SDKs are handled ok // We need to repopulate req.body with a buffer // Client keys are not required in parse-server, but if any have been configured in the server, validate them //  to preserve original behavior. // We do it with mismatching keys to support no-keys config // check if set in the config and compare // All keys mismatch // handle the upgradeToRevocableSession path on it's own // TODO: Determine the correct error scenario.