<commit_before>App = {
  web3Provider: null,
  contracts: {},

  init: function() {
    return App.initWeb3();
  },

  initWeb3: function() {
    // Initialize web3 and set the provider to the testRPC.
    if (typeof web3 !== 'undefined') {
      App.web3Provider = web3.currentProvider;
      web3 = new Web3(web3.currentProvider);
    } else {
      // set the provider you want from Web3.providers
      App.web3Provider = new web3.providers.HttpProvider('http://localhost:8545');
      web3 = new Web3(App.web3Provider);
    }

    return App.initContract();
  },

  initContract: function() {
    $.getJSON('GraivyApp.json', function(data) {
      // Get the necessary contract artifact file and instantiate it with truffle-contract.
      var GraivyAppArtifact = data;
      App.contracts.GraivyApp = TruffleContract(GraivyAppArtifact);

      // Set the provider for our contract.
      App.contracts.GraivyApp.setProvider(App.web3Provider);

      // Use our contract to retieve and mark the adopted pets.
      return App.getUserCount(), App.authenticateUser();
    });

    return App.bindEvents();
  },

  bindEvents: function() {
    $(document).on('click', '#isUser', App.handleUserCheck);
    $(document).on('click', '#insertUser', App.handleInsertUser);
    $(document).on('click', '#deleteUser', App.handleDeleteUser);
    $(document).on('click', '#getUserQualifications', App.handleGetUserQualifications);
    $(document).on('click', '#getUserPermissions', App.handleGetUserPermissions);
    $(document).on('click', '#updateUserQualifications', App.handleUpdateUserQualifications);
    $(document).on('click', '#updateUserPermissions', App.handleUpdateUserPermissions);
  },

  handleInsertUser: function() {
    event.preventDefault();

    console.log('Creating User');

    var graivyAppInstance;

    web3.eth.getAccounts(function(error, accounts) {
      if (error) {
        console.log(error);
      }

      var account = accounts[0];

      App.contracts.GraivyApp.deployed().then(function(instance) {
        graivyAppInstance = instance;

        return graivyAppInstance.insertUser({from: account});
      }).then(function(result) {
        alert('User Created!');
        return App.getUserCount();
      }).catch(function(err) {
        console.log(err.message);
      });
    });
  },

  handleDeleteUser: function() {
    event.preventDefault();

    console.log('Deleting User... ');

    var graivyAppInstance;

    web3.eth.getAccounts(function(error, accounts) {
      if (error) {
        console.log(error);
      }

      var account = accounts[0];

      App.contracts.GraivyApp.deployed().then(function(instance) {
        graivyAppInstance = instance;

        return graivyAppInstance.deleteUser(account, {from: account});
      }).then(function(result) {
        alert('User Deleted!');
        return App.getUserCount();
      }).catch(function(err) {
        console.log(err.message);
      });
    });
  },

  handleGetUserQualifications: function() {
    event.preventDefault();

    var userAddress = $('#GetUserQualificationsAddy').val();

    console.log('Getting qualifications for User ' + userAddress);

    var graivyAppInstance;

    web3.eth.getAccounts(function(error, accounts) {
      if (error) {
        console.log(error);
      }

      var account = accounts[0];

      App.contracts.GraivyApp.deployed().then(function(instance) {
        graivyAppInstance = instance;

        return graivyAppInstance.getUserQualifications(userAddress);
      }).then(function(result) {
        console.log(result);
        //qualifications = result.c;
        //rewardAvailable = result.c[1];
        //index = result.c[2];

        $('#ReturnUserQualifications').text(result);
        //$('#GetUserRewardAvailable').text(rewardAvailable);
        //$('#GetUserIndex').text(index);
        //$('#GetUserAddress').text(account);
      }).catch(function(err) {
        console.log(err.message);
      });
    });
  },

  handleGetUserPermissions: function() {
    event.preventDefault();

    var userAddress = $('#GetUserPermissionsAddy').val();

    console.log('Getting permissions for User ' + userAddress);

    var graivyAppInstance;

    web3.eth.getAccounts(function(error, accounts) {
      if (error) {
        console.log(error);
      }

      var account = accounts[0];

      App.contracts.GraivyApp.deployed().then(function(instance) {
        graivyAppInstance = instance;

        return graivyAppInstance.getUserPermissions(userAddress);
      }).then(function(result) {
        console.log(result);
        //qualifications = result.c;
        //rewardAvailable = result.c[1];
        //index = result.c[2];

        $('#ReturnUserPermissions').text(result);
        //$('#GetUserRewardAvailable').text(rewardAvailable);
        //$('#GetUserIndex').text(index);
        //$('#GetUserAddress').text(account);
      }).catch(function(err) {
        console.log(err.message);
      });
    });
  },

  handleUpdateUserQualifications: function() {
    event.preventDefault();

    var qualifications = parseInt($('#UpdateQualificationsValue').val());
    var userAddress = $('#UpdateQualificationsAddress').val();

    console.log('Updating Qualifications for ' + userAddress);

    var graivyAppInstance;

    web3.eth.getAccounts(function(error, accounts) {
      if (error) {
        console.log(error);
      }

      var account = accounts[0];

      App.contracts.GraivyApp.deployed().then(function(instance) {
        graivyAppInstance = instance;

        return graivyAppInstance.updateUserQualifications(userAddress, qualifications);
      }).then(function(result) {
        alert('User Qualifications updated');
        return App.getUserCount();
      }).catch(function(err) {
        console.log(err.message);
      });
    });
  },

  handleUpdateUserPermissions: function() {
    event.preventDefault();

    var permissions = parseInt($('#UpdatePermissionsValue').val());
    var userAddress = $('#UpdatePermissionsAddress').val();

    console.log('Updating Permissions');

    var graivyAppInstance;

    web3.eth.getAccounts(function(error, accounts) {
      if (error) {
        console.log(error);
      }

      var account = accounts[0];

      App.contracts.GraivyApp.deployed().then(function(instance) {
        graivyAppInstance = instance;

        return graivyAppInstance.updateUserPermissions(userAddress, permissions);
      }).then(function(result) {
        alert('User Permissions updated');
        return App.getUserCount();
      }).catch(function(err) {
        console.log(err.message);
      });
    });
  },

  getUserCount: function(adopters) {
    console.log('Getting user count...');

    var graivyAppInstance;

    web3.eth.getAccounts(function(error, accounts) {
      if (error) {
        console.log(error);
      }

      var account = accounts[0];

      App.contracts.GraivyApp.deployed().then(function(instance) {
        graivyAppInstance = instance;

        return graivyAppInstance.getUserCount();
      }).then(function(result) {
        count = result.c[0];

        $('#GVYUserCount').text(count);
      }).catch(function(err) {
        console.log(err.message);
      });
    });
  },

  authenticateUser: function(adopters, account) {
    console.log('Checking if user...');

    var graivyAppInstance;

    web3.eth.getAccounts(function(error, accounts) {
      if (error) {
        console.log(error);
      }

      var account = accounts[0];

      App.contracts.GraivyApp.deployed().then(function(instance) {
        graivyAppInstance = instance;

        return graivyAppInstance.authenticateUser(account);
      }).then(function(result) {
        if (result == true) {
          $('#GVYUserCheck').text('Welcome back, you are logged in.');
        }
        else $('#GVYUserCheck').text('Please create a user account and login!');
      }).catch(function(err) {
        console.log(err.message);
      });
    });
  }

};

$(function() {
  $(window).load(function() {
    App.init();
  });
});
<commit_msg>fix comments<commit_after>App = {
  web3Provider: null,
  contracts: {},

  init: function() {
    return App.initWeb3();
  },

  initWeb3: function() {
    // Initialize web3 and set the provider to the testRPC.
    if (typeof web3 !== 'undefined') {
      App.web3Provider = web3.currentProvider;
      web3 = new Web3(web3.currentProvider);
    } else {
      // set the provider you want from Web3.providers
      App.web3Provider = new web3.providers.HttpProvider('http://localhost:8545');
      web3 = new Web3(App.web3Provider);
    }

    return App.initContract();
  },

  initContract: function() {
    $.getJSON('GraivyApp.json', function(data) {
      // Get the necessary contract artifact file and instantiate it with truffle-contract.
      var GraivyAppArtifact = data;
      App.contracts.GraivyApp = TruffleContract(GraivyAppArtifact);

      // Set the provider for our contract.
      App.contracts.GraivyApp.setProvider(App.web3Provider);

      // Count users and try to authenticate in background
      return App.getUserCount(), App.authenticateUser();
    });

    return App.bindEvents();
  },

  bindEvents: function() {
    $(document).on('click', '#isUser', App.handleUserCheck);
    $(document).on('click', '#insertUser', App.handleInsertUser);
    $(document).on('click', '#deleteUser', App.handleDeleteUser);
    $(document).on('click', '#getUserQualifications', App.handleGetUserQualifications);
    $(document).on('click', '#getUserPermissions', App.handleGetUserPermissions);
    $(document).on('click', '#updateUserQualifications', App.handleUpdateUserQualifications);
    $(document).on('click', '#updateUserPermissions', App.handleUpdateUserPermissions);
  },

  handleInsertUser: function() {
    event.preventDefault();

    console.log('Creating User');

    var graivyAppInstance;

    web3.eth.getAccounts(function(error, accounts) {
      if (error) {
        console.log(error);
      }

      var account = accounts[0];

      App.contracts.GraivyApp.deployed().then(function(instance) {
        graivyAppInstance = instance;

        return graivyAppInstance.insertUser({from: account});
      }).then(function(result) {
        alert('User Created!');
        return App.getUserCount();
      }).catch(function(err) {
        console.log(err.message);
      });
    });
  },

  handleDeleteUser: function() {
    event.preventDefault();

    console.log('Deleting User... ');

    var graivyAppInstance;

    web3.eth.getAccounts(function(error, accounts) {
      if (error) {
        console.log(error);
      }

      var account = accounts[0];

      App.contracts.GraivyApp.deployed().then(function(instance) {
        graivyAppInstance = instance;

        return graivyAppInstance.deleteUser(account, {from: account});
      }).then(function(result) {
        alert('User Deleted!');
        return App.getUserCount();
      }).catch(function(err) {
        console.log(err.message);
      });
    });
  },

  handleGetUserQualifications: function() {
    event.preventDefault();

    var userAddress = $('#GetUserQualificationsAddy').val();

    console.log('Getting qualifications for User ' + userAddress);

    var graivyAppInstance;

    web3.eth.getAccounts(function(error, accounts) {
      if (error) {
        console.log(error);
      }

      var account = accounts[0];

      App.contracts.GraivyApp.deployed().then(function(instance) {
        graivyAppInstance = instance;

        return graivyAppInstance.getUserQualifications(userAddress);
      }).then(function(result) {
        console.log(result);
        //qualifications = result.c;
        //rewardAvailable = result.c[1];
        //index = result.c[2];

        $('#ReturnUserQualifications').text(result);
        //$('#GetUserRewardAvailable').text(rewardAvailable);
        //$('#GetUserIndex').text(index);
        //$('#GetUserAddress').text(account);
      }).catch(function(err) {
        console.log(err.message);
      });
    });
  },

  handleGetUserPermissions: function() {
    event.preventDefault();

    var userAddress = $('#GetUserPermissionsAddy').val();

    console.log('Getting permissions for User ' + userAddress);

    var graivyAppInstance;

    web3.eth.getAccounts(function(error, accounts) {
      if (error) {
        console.log(error);
      }

      var account = accounts[0];

      App.contracts.GraivyApp.deployed().then(function(instance) {
        graivyAppInstance = instance;

        return graivyAppInstance.getUserPermissions(userAddress);
      }).then(function(result) {
        console.log(result);
        //qualifications = result.c;
        //rewardAvailable = result.c[1];
        //index = result.c[2];

        $('#ReturnUserPermissions').text(result);
        //$('#GetUserRewardAvailable').text(rewardAvailable);
        //$('#GetUserIndex').text(index);
        //$('#GetUserAddress').text(account);
      }).catch(function(err) {
        console.log(err.message);
      });
    });
  },

  handleUpdateUserQualifications: function() {
    event.preventDefault();

    var qualifications = parseInt($('#UpdateQualificationsValue').val());
    var userAddress = $('#UpdateQualificationsAddress').val();

    console.log('Updating Qualifications for ' + userAddress);

    var graivyAppInstance;

    web3.eth.getAccounts(function(error, accounts) {
      if (error) {
        console.log(error);
      }

      var account = accounts[0];

      App.contracts.GraivyApp.deployed().then(function(instance) {
        graivyAppInstance = instance;

        return graivyAppInstance.updateUserQualifications(userAddress, qualifications);
      }).then(function(result) {
        alert('User Qualifications updated');
        return App.getUserCount();
      }).catch(function(err) {
        console.log(err.message);
      });
    });
  },

  handleUpdateUserPermissions: function() {
    event.preventDefault();

    var permissions = parseInt($('#UpdatePermissionsValue').val());
    var userAddress = $('#UpdatePermissionsAddress').val();

    console.log('Updating Permissions');

    var graivyAppInstance;

    web3.eth.getAccounts(function(error, accounts) {
      if (error) {
        console.log(error);
      }

      var account = accounts[0];

      App.contracts.GraivyApp.deployed().then(function(instance) {
        graivyAppInstance = instance;

        return graivyAppInstance.updateUserPermissions(userAddress, permissions);
      }).then(function(result) {
        alert('User Permissions updated');
        return App.getUserCount();
      }).catch(function(err) {
        console.log(err.message);
      });
    });
  },

  getUserCount: function(adopters) {
    console.log('Getting user count...');

    var graivyAppInstance;

    web3.eth.getAccounts(function(error, accounts) {
      if (error) {
        console.log(error);
      }

      var account = accounts[0];

      App.contracts.GraivyApp.deployed().then(function(instance) {
        graivyAppInstance = instance;

        return graivyAppInstance.getUserCount();
      }).then(function(result) {
        count = result.c[0];

        $('#GVYUserCount').text(count);
      }).catch(function(err) {
        console.log(err.message);
      });
    });
  },

  authenticateUser: function(adopters, account) {
    console.log('Checking if user...');

    var graivyAppInstance;

    web3.eth.getAccounts(function(error, accounts) {
      if (error) {
        console.log(error);
      }

      var account = accounts[0];

      App.contracts.GraivyApp.deployed().then(function(instance) {
        graivyAppInstance = instance;

        return graivyAppInstance.authenticateUser(account);
      }).then(function(result) {
        if (result == true) {
          $('#GVYUserCheck').text('Welcome back, you are logged in.');
        }
        else $('#GVYUserCheck').text('Please create a user account and login!');
      }).catch(function(err) {
        console.log(err.message);
      });
    });
  }

};

$(function() {
  $(window).load(function() {
    App.init();
  });
});
<|endoftext|>


<commit_before>import _ from 'lodash';
import xml2js from 'xml2js';

// Escape special characters for use in Mongo query
function escapeRegExp(str) {
  return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&');
}

export default class Controller {
  constructor(app, wss) {
    // Referenecs to the express app and websocketserver connection
    this.app = app;
    this.wss = wss;

    // Mongoose
    this.sort = {};
    this.select = null;

    // Controller defined routes
    this.routes = [];

    // Controller defined middleware
    this.pre = []; // run before route middleware
    this.before = []; // run after route middleware but before route handler
    this.after = []; // run after route handler

    // Internal middleware
    this._begin = [];
    this._end = [
      this.successResponse,
      this.errorResponse,
      this.finalResponse,
    ];

    // Support optional XML response format
    this.xmlBuilder = new xml2js.Builder({
      renderOpts: {
        pretty: false,
      },
    });
  }

  throwError(message, status = 500) {
    const err = new Error(message);
    err.status = status;
    throw err;
  }

  /* Middleware */

  // TODO: Parse created_at/updated_at bounding

  /**
   * http://mongoosejs.com/docs/api.html#query_Query-select
   */
  parseFields(req) {
    let select;
    if (_.isString(req.query.fields)) {
      select = req.query.fields.replace(/\s+/g, '').replace(/,/g, ' ');
    }

    return select;
  }

  /**
   * http://mongoosejs.com/docs/api.html#query_Query-skip
   * http://mongoosejs.com/docs/api.html#query_Query-limit
   * http://mongoosejs.com/docs/api.html#query_Query-sort
   */
  parseSkipLimitSortOrder(req) {
    // Skip and Limit
    let skip = _.parseInt(req.query.skip || req.query.offset) || 0;
    const limit = _.parseInt(req.query.limit || req.query.count) || 0;

    // Support using `page` instead of `skip`
    const page = _.parseInt(req.query.page) || 0;
    if (page > 0) {
      // IMPORTANT! `page` starts at 1
      // if `page` is specified, we override `skip`
      // calculate skip based on page and limit
      // lets assume limit is 100
      // page 1 is skip 0
      // page 2 is skip 100
      // etc...
      skip = (page - 1) * limit;
    }

    // Sort and Sort Order
    const sort = {};
    if (req.query.sort) {
      let order;
      switch (req.query.order) {
        case '1':
        case 'asc':
          order = 1;
          break;
        case '-1':
        case 'desc':
          order = -1;
          break;
        default:
          order = 1;
          break;
      }
      sort[req.query.sort] = order;
    }

    return {
      skip,
      limit,
      page,
      sort,
    };
  }

  parseQueryParams(req) {
    if (!this.queryParams) {
      return {};
    }

    const query = {};
    const queries = [];
    const params = _.pick(req.query, _.keys(this.queryParams));
    const logicalOperator = `$${(req.query.logical || 'and').toLowerCase().replace(/[@\s]/g, '')}`;

    _.forEach(params, (val, key) => {
      // If value is `*`, ignore this param
      if (val === '*') {
        return;
      }

      // Make sure val is a string (should usually be from express)
      if (!_.isString(val)) {
        val = val.toString();
      }

      // Support `,` as `$or` for each param
      let vals = val.split(',');

      // No value, ignore this param
      if (vals.length === 0) {
        return;
      }

      // The built query filter
      const filter = {};

      // Get param type defined in `queryParams`
      const type = this.queryParams[key];

      // Deal with different param types
      if (type === 'bool' || type === 'boolean') {
        vals = _.map(vals, (v) => {
          if (v === 'true' || v === 'yes' || v === '1') {
            return true;
          } else if (v === 'false' || v === 'no' || v === '0') {
            return false;
          }

          return false;
        });
      } else if (type === 'string') {
        // strings and objectid
        // no transformation
      } else if (type === 'regex') {
        // regex case insensitive and escaping special characters
        vals = _.map(vals, v => ({
          $regex: escapeRegExp(v),
          $options: 'i',
        }));
      } else if (type === 'integer') {
        // integers
        vals = _.map(vals, v => _.parseInt(v));
      } else if (type === 'float') {
        // floats
        vals = _.map(vals, v => parseFloat(v));
      } else {
        // invalid or unknown type
        return;
      }

      // If there is only one val, no need to use `$or`
      if (vals.length === 1) {
        // Treat `[]` as empty array
        filter[key] = vals[0] === '[]' ? [] : vals[0];
      } else {
        const orExpr = [];
        _.forEach(vals, (orVal) => {
          const orClause = {};
          orClause[key] = orVal;
          orExpr.push(orClause);
        });
        filter.$or = orExpr;
      }

      queries.push(filter);
    });

    // Combine the query
    if (queries.length === 1) {
      _.assign(query, queries[0]);
    } else if (queries.length > 0) {
      query[logicalOperator] = queries;
    }

    return query;
  }

  successResponse(req, res, next) {
    const envelope = {
      meta: {
        statusCode: res.statusCode,
      },
      data: res.data || {},
    };

    // Paging (optional)
    if (_.isPlainObject(res.paging)) {
      envelope.meta.paging = res.paging;
    }

    // Response
    res.envelope = res.statusCode !== 204 ? envelope : undefined;

    next();
  }

  /**
   * Error
   * - statusCode (http status code - number)
   * - type (internal error type - string)
   * - message (human readable - string)
   * - line (stack trace - string)
   */
  errorResponse(err, req, res, next) {
    const error = new Error();

    if (/E11000/.test(err.message)) {
      error.message = 'Conflict';
      error.statusCode = 409;
      error.type = 'MONGODB_E11000';
    } else if (err.name === 'ValidationError') {
      // Mongoose Validation
      error.message = _.map(err.errors, 'message').join(', ');
      error.statusCode = 400;
      error.type = 'MONGOOSE_VALIDATION_ERROR';
      error.meta = {
        errors: err.errors,
      };
    } else if (_.isFunction(req.validationErrors) && req.validationErrors().length) {
      // Express Validator
      const messages = req.validationErrors().map(ve => `[${ve.param} -> ${ve.msg}]`);
      error.message = messages.join(', ');
      error.statusCode = 400;
      error.type = 'EXPRESS_VALIDATION_ERROR';
      error.meta = {
        validationErrors: req.validationErrors(),
      };
    } else {
      error.message = err.message || 'Internal Server Error';
      error.statusCode = _.parseInt(err.statusCode) || 500;
    }

    // Pass on any `meta` data from the original error
    error.meta = err.meta || error.meta;

    // Pass on any `data` from the original error
    error.data = err.data || {};

    // Try and extract the line in which the error was caught
    if (err.stack) {
      try {
        error.line = err.stack.split('\n')[1].match(/at\s(.*)/)[1];
      } catch (e) {
        error.line = null;
      }
    }

    let defaultErrorType;
    switch (error.statusCode) {
      case 400:
        defaultErrorType = 'BAD_REQUEST';
        break;
      case 401:
        defaultErrorType = 'UNAUTHORIZED';
        break;
      case 402:
      case 403:
        defaultErrorType = 'FORBIDDEN';
        break;
      case 404:
        defaultErrorType = 'NOT_FOUND';
        break;
      case 405:
        defaultErrorType = 'METHOD_NOT_ALLOWED';
        break;
      case 406:
        defaultErrorType = 'NOT_ACCEPTABLE';
        break;
      case 409:
        defaultErrorType = 'CONFLICT';
        break;
      case 410:
        defaultErrorType = 'GONE';
        break;
      case 501:
        defaultErrorType = 'NOT_IMPLEMENTED';
        break;
      case 500:
      default:
        defaultErrorType = 'INTERNAL_SERVER_ERROR';
        break;
    }

    const envelope = {
      meta: {
        statusCode: error.statusCode,
        errorType: error.type || defaultErrorType,
        errorMessage: error.message,
      },
      data: error.data,
    };

    // Error Line from Stack (optional)
    if (error.line) {
      envelope.meta.errorLine = error.line;
    }

    // Response
    res.status(error.statusCode);
    res.error = error;
    res.err = error;
    res.envelope = envelope;

    next();
  }

  /**
   * Attempts to respond to the request with data or error
   * Can respond in either `json` or `xml` format
   * Always calls `next`
   */
  finalResponse(req, res, next) {
    // If we timed out before managing to respond, don't send the response
    if (res.headersSent) {
      next();
      return;
    }

    // Look for `.json` or `.xml` extension in path
    // And override request accept header
    if (/.json$/.test(req.path)) {
      req.headers.accept = 'application/json';
    } else if (/.xml$/.test(req.path)) {
      req.headers.accept = 'application/xml';
    }

    // Use request accept header to determine response content-type
    res.format({
      json() {
        res.jsonp(res.envelope);
      },
      xml() {
        try {
          const xmlData = JSON.parse(JSON.stringify(res.data));
          const xml = this.xmlBuilder.buildObject(xmlData);
          res.set('Content-Type', 'application/xml; charset=utf-8');
          res.send(xml);
        } catch (e) {
          res.status(500).end();
        }
      },
      text() {
        res.send(res.envelope);
      },
      default() {
        res.status(406).send('Not Acceptable');
      },
    });

    next();
  }
}
<commit_msg>bug: fix this context in controller<commit_after>import _ from 'lodash';
import xml2js from 'xml2js';

// Escape special characters for use in Mongo query
function escapeRegExp(str) {
  return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&');
}

export default class Controller {
  constructor(app, wss) {
    // Referenecs to the express app and websocketserver connection
    this.app = app;
    this.wss = wss;

    // Mongoose
    this.sort = {};
    this.select = null;

    // Controller defined routes
    this.routes = [];

    // Controller defined middleware
    this.pre = []; // run before route middleware
    this.before = []; // run after route middleware but before route handler
    this.after = []; // run after route handler

    // Internal middleware
    this._begin = [];
    this._end = [
      this.successResponse,
      this.errorResponse,
      this.finalResponse,
    ];

    // Support optional XML response format
    this.xmlBuilder = new xml2js.Builder({
      renderOpts: {
        pretty: false,
      },
    });
  }

  throwError(message, status = 500) {
    const err = new Error(message);
    err.status = status;
    throw err;
  }

  /* Middleware */

  // TODO: Parse created_at/updated_at bounding

  /**
   * http://mongoosejs.com/docs/api.html#query_Query-select
   */
  parseFields(req) {
    let select;
    if (_.isString(req.query.fields)) {
      select = req.query.fields.replace(/\s+/g, '').replace(/,/g, ' ');
    }

    return select;
  }

  /**
   * http://mongoosejs.com/docs/api.html#query_Query-skip
   * http://mongoosejs.com/docs/api.html#query_Query-limit
   * http://mongoosejs.com/docs/api.html#query_Query-sort
   */
  parseSkipLimitSortOrder(req) {
    // Skip and Limit
    let skip = _.parseInt(req.query.skip || req.query.offset) || 0;
    const limit = _.parseInt(req.query.limit || req.query.count) || 0;

    // Support using `page` instead of `skip`
    const page = _.parseInt(req.query.page) || 0;
    if (page > 0) {
      // IMPORTANT! `page` starts at 1
      // if `page` is specified, we override `skip`
      // calculate skip based on page and limit
      // lets assume limit is 100
      // page 1 is skip 0
      // page 2 is skip 100
      // etc...
      skip = (page - 1) * limit;
    }

    // Sort and Sort Order
    const sort = {};
    if (req.query.sort) {
      let order;
      switch (req.query.order) {
        case '1':
        case 'asc':
          order = 1;
          break;
        case '-1':
        case 'desc':
          order = -1;
          break;
        default:
          order = 1;
          break;
      }
      sort[req.query.sort] = order;
    }

    return {
      skip,
      limit,
      page,
      sort,
    };
  }

  parseQueryParams(req) {
    if (!this.queryParams) {
      return {};
    }

    const query = {};
    const queries = [];
    const params = _.pick(req.query, _.keys(this.queryParams));
    const logicalOperator = `$${(req.query.logical || 'and').toLowerCase().replace(/[@\s]/g, '')}`;

    _.forEach(params, (val, key) => {
      // If value is `*`, ignore this param
      if (val === '*') {
        return;
      }

      // Make sure val is a string (should usually be from express)
      if (!_.isString(val)) {
        val = val.toString();
      }

      // Support `,` as `$or` for each param
      let vals = val.split(',');

      // No value, ignore this param
      if (vals.length === 0) {
        return;
      }

      // The built query filter
      const filter = {};

      // Get param type defined in `queryParams`
      const type = this.queryParams[key];

      // Deal with different param types
      if (type === 'bool' || type === 'boolean') {
        vals = _.map(vals, (v) => {
          if (v === 'true' || v === 'yes' || v === '1') {
            return true;
          } else if (v === 'false' || v === 'no' || v === '0') {
            return false;
          }

          return false;
        });
      } else if (type === 'string') {
        // strings and objectid
        // no transformation
      } else if (type === 'regex') {
        // regex case insensitive and escaping special characters
        vals = _.map(vals, v => ({
          $regex: escapeRegExp(v),
          $options: 'i',
        }));
      } else if (type === 'integer') {
        // integers
        vals = _.map(vals, v => _.parseInt(v));
      } else if (type === 'float') {
        // floats
        vals = _.map(vals, v => parseFloat(v));
      } else {
        // invalid or unknown type
        return;
      }

      // If there is only one val, no need to use `$or`
      if (vals.length === 1) {
        // Treat `[]` as empty array
        filter[key] = vals[0] === '[]' ? [] : vals[0];
      } else {
        const orExpr = [];
        _.forEach(vals, (orVal) => {
          const orClause = {};
          orClause[key] = orVal;
          orExpr.push(orClause);
        });
        filter.$or = orExpr;
      }

      queries.push(filter);
    });

    // Combine the query
    if (queries.length === 1) {
      _.assign(query, queries[0]);
    } else if (queries.length > 0) {
      query[logicalOperator] = queries;
    }

    return query;
  }

  successResponse(req, res, next) {
    const envelope = {
      meta: {
        statusCode: res.statusCode,
      },
      data: res.data || {},
    };

    // Paging (optional)
    if (_.isPlainObject(res.paging)) {
      envelope.meta.paging = res.paging;
    }

    // Response
    res.envelope = res.statusCode !== 204 ? envelope : undefined;

    next();
  }

  /**
   * Error
   * - statusCode (http status code - number)
   * - type (internal error type - string)
   * - message (human readable - string)
   * - line (stack trace - string)
   */
  errorResponse(err, req, res, next) {
    const error = new Error();

    if (/E11000/.test(err.message)) {
      error.message = 'Conflict';
      error.statusCode = 409;
      error.type = 'MONGODB_E11000';
    } else if (err.name === 'ValidationError') {
      // Mongoose Validation
      error.message = _.map(err.errors, 'message').join(', ');
      error.statusCode = 400;
      error.type = 'MONGOOSE_VALIDATION_ERROR';
      error.meta = {
        errors: err.errors,
      };
    } else if (_.isFunction(req.validationErrors) && req.validationErrors().length) {
      // Express Validator
      const messages = req.validationErrors().map(ve => `[${ve.param} -> ${ve.msg}]`);
      error.message = messages.join(', ');
      error.statusCode = 400;
      error.type = 'EXPRESS_VALIDATION_ERROR';
      error.meta = {
        validationErrors: req.validationErrors(),
      };
    } else {
      error.message = err.message || 'Internal Server Error';
      error.statusCode = _.parseInt(err.statusCode) || 500;
    }

    // Pass on any `meta` data from the original error
    error.meta = err.meta || error.meta;

    // Pass on any `data` from the original error
    error.data = err.data || {};

    // Try and extract the line in which the error was caught
    if (err.stack) {
      try {
        error.line = err.stack.split('\n')[1].match(/at\s(.*)/)[1];
      } catch (e) {
        error.line = null;
      }
    }

    let defaultErrorType;
    switch (error.statusCode) {
      case 400:
        defaultErrorType = 'BAD_REQUEST';
        break;
      case 401:
        defaultErrorType = 'UNAUTHORIZED';
        break;
      case 402:
      case 403:
        defaultErrorType = 'FORBIDDEN';
        break;
      case 404:
        defaultErrorType = 'NOT_FOUND';
        break;
      case 405:
        defaultErrorType = 'METHOD_NOT_ALLOWED';
        break;
      case 406:
        defaultErrorType = 'NOT_ACCEPTABLE';
        break;
      case 409:
        defaultErrorType = 'CONFLICT';
        break;
      case 410:
        defaultErrorType = 'GONE';
        break;
      case 501:
        defaultErrorType = 'NOT_IMPLEMENTED';
        break;
      case 500:
      default:
        defaultErrorType = 'INTERNAL_SERVER_ERROR';
        break;
    }

    const envelope = {
      meta: {
        statusCode: error.statusCode,
        errorType: error.type || defaultErrorType,
        errorMessage: error.message,
      },
      data: error.data,
    };

    // Error Line from Stack (optional)
    if (error.line) {
      envelope.meta.errorLine = error.line;
    }

    // Response
    res.status(error.statusCode);
    res.error = error;
    res.err = error;
    res.envelope = envelope;

    next();
  }

  /**
   * Attempts to respond to the request with data or error
   * Can respond in either `json` or `xml` format
   * Always calls `next`
   */
  finalResponse(req, res, next) {
    // If we timed out before managing to respond, don't send the response
    if (res.headersSent) {
      next();
      return;
    }

    // Look for `.json` or `.xml` extension in path
    // And override request accept header
    if (/.json$/.test(req.path)) {
      req.headers.accept = 'application/json';
    } else if (/.xml$/.test(req.path)) {
      req.headers.accept = 'application/xml';
    }

    // Use request accept header to determine response content-type
    const xmlBuilder = this.xmlBuilder;
    res.format({
      json() {
        res.jsonp(res.envelope);
      },
      xml() {
        try {
          const xmlData = JSON.parse(JSON.stringify(res.envelope));
          const xml = xmlBuilder.buildObject(xmlData);
          res.set('Content-Type', 'application/xml; charset=utf-8');
          res.send(xml);
        } catch (e) {
          res.status(500).end();
        }
      },
      text() {
        res.send(res.envelope);
      },
      default() {
        res.status(406).send('Not Acceptable');
      },
    });

    next();
  }
}
<|endoftext|>


<commit_before>const URL = require('url');
const ghGot = require('gh-got');
const delay = require('delay');
const parseLinkHeader = require('parse-link-header');
const pAll = require('p-all');

const hostRules = require('../../util/host-rules');
const { maskToken } = require('../../util/mask');

let cache = {};
let stats = {};

async function get(path, options, retries = 5) {
  const { host } = URL.parse(path);
  const opts = {
    ...hostRules.find({ platform: 'github', host }),
    ...options,
  };
  opts.baseUrl = opts.endpoint;
  delete opts.endpoint;
  const method = opts.method || 'get';
  const useCache = opts.useCache || true;
  if (method.toLowerCase() === 'post' && path === 'graphql') {
    // GitHub Enterprise uses unversioned graphql path
    opts.baseUrl = opts.baseUrl.replace(/\/v3\/?$/, '/');
  }
  if (method === 'get' && useCache && cache[path]) {
    logger.trace({ path }, 'Returning cached result');
    return cache[path];
  }
  logger.trace(`${method.toUpperCase()} ${path}`);
  stats.requests = (stats.requests || []).concat([
    method.toUpperCase() + ' ' + path,
  ]);
  try {
    if (global.appMode) {
      const appAccept = 'application/vnd.github.machine-man-preview+json';
      opts.headers = Object.assign(
        {},
        {
          accept: appAccept,
          'user-agent':
            process.env.RENOVATE_USER_AGENT ||
            'https://github.com/renovatebot/renovate',
        },
        opts.headers
      );
      if (opts.headers.accept !== appAccept) {
        opts.headers.accept = `${appAccept}, ${opts.headers.accept}`;
      }
    }
    const res = await ghGot(path, opts);
    if (res && res.headers) {
      stats.rateLimit = res.headers['x-ratelimit-limit'];
      stats.rateLimitRemaining = res.headers['x-ratelimit-remaining'];
    }
    if (opts.paginate) {
      // Check if result is paginated
      const pageLimit = opts.pageLimit || 10;
      const linkHeader = parseLinkHeader(res.headers.link);
      if (linkHeader && linkHeader.next && linkHeader.last) {
        let lastPage = +linkHeader.last.page;
        if (!process.env.RENOVATE_PAGINATE_ALL && opts.paginate !== 'all') {
          lastPage = Math.min(pageLimit, lastPage);
        }
        const pageNumbers = Array.from(
          new Array(lastPage),
          (x, i) => i + 1
        ).slice(1);
        const queue = pageNumbers.map(page => () => {
          const url = URL.parse(linkHeader.next.url, true);
          delete url.search;
          url.query.page = page;
          return get(URL.format(url), { ...opts, paginate: false }, retries);
        });
        const pages = await pAll(queue, { concurrency: 5 });
        res.body = res.body.concat(
          ...pages.filter(Boolean).map(page => page.body)
        );
      }
    }
    if (
      method === 'get' &&
      (path.startsWith('repos/') ||
        path.startsWith('https://api.github.com/repos/'))
    ) {
      cache[path] = res;
    }
    // istanbul ignore if
    if (method === 'POST' && path === 'graphql') {
      const goodResult = '{"data":{';
      if (res.body.startsWith(goodResult)) {
        if (retries === 0) {
          logger.info('Recovered graphql query');
        }
      } else if (retries > 0) {
        logger.info('Retrying graphql query');
        opts.body = opts.body.replace('first: 100', 'first: 25');
        return get(path, opts, 0);
      }
    }
    return res;
  } catch (err) {
    if (
      err.name === 'RequestError' &&
      (err.code === 'ENOTFOUND' || err.code === 'ETIMEDOUT')
    ) {
      throw new Error('platform-failure');
    }
    if (err.name === 'ParseError') {
      throw new Error('platform-failure');
    }
    if (err.statusCode >= 500 && err.statusCode < 600) {
      if (retries > 0) {
        logger.info(
          { statusCode: err.statusCode, message: err.message },
          `Retrying request`
        );

        await delay(5000 / retries);

        return get(path, opts, retries - 1);
      }
      throw new Error('platform-failure');
    }
    if (
      err.statusCode === 403 &&
      err.message &&
      err.message.startsWith('You have triggered an abuse detection mechanism')
    ) {
      if (retries > 0) {
        logger.info(
          {
            headers: err.headers,
            path,
            statusCode: err.statusCode,
            message: err.message,
          },
          `Retrying request`
        );

        await delay(180000 / (retries * retries));

        return get(path, opts, 0);
      }
      // istanbul ignore next
      throw new Error('platform-failure');
    }
    if (
      err.statusCode === 403 &&
      err.message &&
      err.message.startsWith(
        'Upgrade to GitHub Pro or make this repository public to enable this feature'
      )
    ) {
      // istanbul ignore next
      throw err;
    }
    if (
      err.statusCode === 403 &&
      err.message &&
      err.message.includes('rate limit exceeded')
    ) {
      logger.info({ err, headers: err.headers }, 'Rate limit exceeded');
      throw new Error('rate-limit-exceeded');
    } else if (
      err.statusCode === 403 &&
      err.message &&
      err.message.includes('blobs up to 1 MB in size')
    ) {
      throw err;
    } else if (
      err.statusCode === 403 &&
      err.message &&
      err.message.startsWith('Resource not accessible by integration')
    ) {
      logger.debug({ err }, 'Unauthorized');
      throw new Error('integration-unauthorized');
    } else if (err.statusCode === 403) {
      if (retries > 0) {
        logger.info(
          { statusCode: err.statusCode, message: err.message },
          `Retrying request`
        );

        await delay(60000 / (retries * retries));

        return get(path, opts, retries - 1);
      }
    } else if (
      err.statusCode === 401 &&
      err.message &&
      err.message.includes('Bad credentials')
    ) {
      const rateLimit = err.headers ? err.headers['x-ratelimit-limit'] : -1;
      logger.info(
        {
          token: maskToken(opts.token),
          err,
        },
        'Bad credentials'
      );
      if (rateLimit === '60') {
        throw new Error('platform-failure');
      }
      throw new Error('bad-credentials');
    }
    throw err;
  }
}

const helpers = ['get', 'post', 'put', 'patch', 'head', 'delete'];

for (const x of helpers) {
  get[x] = (url, opts) =>
    get(url, Object.assign({}, opts, { method: x.toUpperCase() }));
}

get.setAppMode = function setAppMode() {
  // no-op
};

get.reset = function reset() {
  cache = null;
  cache = {};
  // istanbul ignore if
  if (stats.requests && stats.requests.length > 1) {
    logger.info(
      {
        rateLimit: parseInt(stats.rateLimit, 10),
        requestCount: stats.requests.length,
        rateLimitRemaining: parseInt(stats.rateLimitRemaining, 10),
      },
      'Request stats'
    );
    stats.requests.sort();
    logger.debug({ requests: stats.requests }, 'All requests');
    stats = {};
  }
};

module.exports = get;
<commit_msg>fix(github): log full err if failing a 5xx response<commit_after>const URL = require('url');
const ghGot = require('gh-got');
const delay = require('delay');
const parseLinkHeader = require('parse-link-header');
const pAll = require('p-all');

const hostRules = require('../../util/host-rules');
const { maskToken } = require('../../util/mask');

let cache = {};
let stats = {};

async function get(path, options, retries = 5) {
  const { host } = URL.parse(path);
  const opts = {
    ...hostRules.find({ platform: 'github', host }),
    ...options,
  };
  opts.baseUrl = opts.endpoint;
  delete opts.endpoint;
  const method = opts.method || 'get';
  const useCache = opts.useCache || true;
  if (method.toLowerCase() === 'post' && path === 'graphql') {
    // GitHub Enterprise uses unversioned graphql path
    opts.baseUrl = opts.baseUrl.replace(/\/v3\/?$/, '/');
  }
  if (method === 'get' && useCache && cache[path]) {
    logger.trace({ path }, 'Returning cached result');
    return cache[path];
  }
  logger.trace(`${method.toUpperCase()} ${path}`);
  stats.requests = (stats.requests || []).concat([
    method.toUpperCase() + ' ' + path,
  ]);
  try {
    if (global.appMode) {
      const appAccept = 'application/vnd.github.machine-man-preview+json';
      opts.headers = Object.assign(
        {},
        {
          accept: appAccept,
          'user-agent':
            process.env.RENOVATE_USER_AGENT ||
            'https://github.com/renovatebot/renovate',
        },
        opts.headers
      );
      if (opts.headers.accept !== appAccept) {
        opts.headers.accept = `${appAccept}, ${opts.headers.accept}`;
      }
    }
    const res = await ghGot(path, opts);
    if (res && res.headers) {
      stats.rateLimit = res.headers['x-ratelimit-limit'];
      stats.rateLimitRemaining = res.headers['x-ratelimit-remaining'];
    }
    if (opts.paginate) {
      // Check if result is paginated
      const pageLimit = opts.pageLimit || 10;
      const linkHeader = parseLinkHeader(res.headers.link);
      if (linkHeader && linkHeader.next && linkHeader.last) {
        let lastPage = +linkHeader.last.page;
        if (!process.env.RENOVATE_PAGINATE_ALL && opts.paginate !== 'all') {
          lastPage = Math.min(pageLimit, lastPage);
        }
        const pageNumbers = Array.from(
          new Array(lastPage),
          (x, i) => i + 1
        ).slice(1);
        const queue = pageNumbers.map(page => () => {
          const url = URL.parse(linkHeader.next.url, true);
          delete url.search;
          url.query.page = page;
          return get(URL.format(url), { ...opts, paginate: false }, retries);
        });
        const pages = await pAll(queue, { concurrency: 5 });
        res.body = res.body.concat(
          ...pages.filter(Boolean).map(page => page.body)
        );
      }
    }
    if (
      method === 'get' &&
      (path.startsWith('repos/') ||
        path.startsWith('https://api.github.com/repos/'))
    ) {
      cache[path] = res;
    }
    // istanbul ignore if
    if (method === 'POST' && path === 'graphql') {
      const goodResult = '{"data":{';
      if (res.body.startsWith(goodResult)) {
        if (retries === 0) {
          logger.info('Recovered graphql query');
        }
      } else if (retries > 0) {
        logger.info('Retrying graphql query');
        opts.body = opts.body.replace('first: 100', 'first: 25');
        return get(path, opts, 0);
      }
    }
    return res;
  } catch (err) {
    if (
      err.name === 'RequestError' &&
      (err.code === 'ENOTFOUND' || err.code === 'ETIMEDOUT')
    ) {
      throw new Error('platform-failure');
    }
    if (err.name === 'ParseError') {
      throw new Error('platform-failure');
    }
    if (err.statusCode >= 500 && err.statusCode < 600) {
      if (retries > 0) {
        logger.info(
          { statusCode: err.statusCode, message: err.message },
          `Retrying request`
        );

        await delay(5000 / retries);

        return get(path, opts, retries - 1);
      }
      logger.info({ err }, 'Giving up on GitHub 5xx error');
      throw new Error('platform-failure');
    }
    if (
      err.statusCode === 403 &&
      err.message &&
      err.message.startsWith('You have triggered an abuse detection mechanism')
    ) {
      if (retries > 0) {
        logger.info(
          {
            headers: err.headers,
            path,
            statusCode: err.statusCode,
            message: err.message,
          },
          `Retrying request`
        );

        await delay(180000 / (retries * retries));

        return get(path, opts, 0);
      }
      // istanbul ignore next
      throw new Error('platform-failure');
    }
    if (
      err.statusCode === 403 &&
      err.message &&
      err.message.startsWith(
        'Upgrade to GitHub Pro or make this repository public to enable this feature'
      )
    ) {
      // istanbul ignore next
      throw err;
    }
    if (
      err.statusCode === 403 &&
      err.message &&
      err.message.includes('rate limit exceeded')
    ) {
      logger.info({ err, headers: err.headers }, 'Rate limit exceeded');
      throw new Error('rate-limit-exceeded');
    } else if (
      err.statusCode === 403 &&
      err.message &&
      err.message.includes('blobs up to 1 MB in size')
    ) {
      throw err;
    } else if (
      err.statusCode === 403 &&
      err.message &&
      err.message.startsWith('Resource not accessible by integration')
    ) {
      logger.debug({ err }, 'Unauthorized');
      throw new Error('integration-unauthorized');
    } else if (err.statusCode === 403) {
      if (retries > 0) {
        logger.info(
          { statusCode: err.statusCode, message: err.message },
          `Retrying request`
        );

        await delay(60000 / (retries * retries));

        return get(path, opts, retries - 1);
      }
    } else if (
      err.statusCode === 401 &&
      err.message &&
      err.message.includes('Bad credentials')
    ) {
      const rateLimit = err.headers ? err.headers['x-ratelimit-limit'] : -1;
      logger.info(
        {
          token: maskToken(opts.token),
          err,
        },
        'Bad credentials'
      );
      if (rateLimit === '60') {
        throw new Error('platform-failure');
      }
      throw new Error('bad-credentials');
    }
    throw err;
  }
}

const helpers = ['get', 'post', 'put', 'patch', 'head', 'delete'];

for (const x of helpers) {
  get[x] = (url, opts) =>
    get(url, Object.assign({}, opts, { method: x.toUpperCase() }));
}

get.setAppMode = function setAppMode() {
  // no-op
};

get.reset = function reset() {
  cache = null;
  cache = {};
  // istanbul ignore if
  if (stats.requests && stats.requests.length > 1) {
    logger.info(
      {
        rateLimit: parseInt(stats.rateLimit, 10),
        requestCount: stats.requests.length,
        rateLimitRemaining: parseInt(stats.rateLimitRemaining, 10),
      },
      'Request stats'
    );
    stats.requests.sort();
    logger.debug({ requests: stats.requests }, 'All requests');
    stats = {};
  }
};

module.exports = get;
<|endoftext|>


<commit_before>/**
 * Module dependencies.
 */

var util = require('util');
var https = require('https');
var http = require('http');
var url = require('url');
var fs = require('fs');
var ejs = require('ejs');
var qs = require('querystring');
var BaseHttpPoller = require('../http/baseHttpPoller');

// The http module lacks proxy support. Let's monkey-patch it.
require('../../proxy');

http.globalAgent.maxSockets = 10000;
https.globalAgent.maxSockets = 10000;

/**
 * HTTPS Poller, to check web pages served via SSL
 *
 * @param {Mixed} Poller Target (e.g. URL)
 * @param {Number} Poller timeout in milliseconds. Without response before this duration, the poller stops and executes the error callback.
 * @param {Function} Error/success callback
 * @api   public
 */
function HttpsPoller(target, timeout, callback) {
    HttpsPoller.super_.call(this, target, timeout, callback);
}

util.inherits(HttpsPoller, BaseHttpPoller);

HttpsPoller.type = 'https+oauth';

HttpsPoller.validateTarget = function (target) {
    return url.parse(target).protocol == 'https:';
};

getAccessToken = function (self, oauthEndpoint, params, credentials, onSuccess, onError) {
    try {
        var req = https.request(oauthEndpoint, function (res) {
          oauthEndpoint.agent = false;
          res.setEncoding('utf8');

            if (res.statusCode < 400) {
                body = "";
                res.on('data', function (chunk) {
                    body += chunk;
                });

                res.on('end', function () {
                    try {
                        var token;
                        if (typeof credentials != 'undefined' && credentials.response_type === 'token'){
                            token = res.headers.location.match(/(?:access_token=)([A-Za-z0-9]+)/)[1];
                        }
                        else {
                            var jsonBody = JSON.parse(body);
                            token = jsonBody.access_token || jsonBody.accessToken;
                        }
                        onSuccess(self, token);
                    } catch (err) {
                        onError(self, {
                            name: "InvalidResponseData",
                            message: "oauth authentication failed, invalid data in response"
                        });
                    }
                });
            } else {
                req.abort();
                onError(self, {
                    name: "InvalidResponseStatus",
                    message: "oauth authentication failed, invalid status (" + res.statusCode + ") in response"
                });
            }
        });

        req.setTimeout(10000, function() {
          req.abort();
        });

        req.on('error', function (err) {
            onError(self, err);
        });
        if (typeof params != 'undefined') {
            req.write(qs.stringify(params), "utf-8");
        } else if (typeof credentials != 'undefined') {
            if (credentials.response_type || credentials.grant_type ) {
                req.write(qs.stringify(credentials), "utf-8");
            }
            else {
                req.write(JSON.stringify(credentials), "utf-8");
            }
        }
        req.end();
    } catch (err) {
        onError(self, {
            name: "UnknownError",
            message: "oauth authentication failed, an unknown error occured (" + err.message + ")"
        });
    }
}

/**
 * Launch the actual polling
 *
 * @api   public
 */
HttpsPoller.prototype.poll = function (secure) {
    getAccessToken(this, this.target.endpoint, this.target.params, this.target.credentials, function (self, token) {
        HttpsPoller.super_.prototype.poll.call(self);
        secure = typeof secure !== 'undefined' ? secure : true;
        try {
            var options = {
                agent: false,
                hostname: self.target.hostname,
                port: self.target.port,
                path: self.target.path,
                method: 'GET',
                headers: {
                    "Authorization": "Bearer " + token
                }
            };

            if (secure) {
                self.request = https.request(options, self.onResponseCallback.bind(self));
            } else {
                self.request = http.request(options, self.onResponseCallback.bind(self));
            }
        } catch (err) {
            return self.onErrorCallback(err);
        }
        self.request.on('error', self.onErrorCallback.bind(self));
        self.request.end();
    }, function (self, err) {
        HttpsPoller.super_.prototype.poll.call(self);
        return self.onErrorCallback(err);
    });
};

// see inherited function BaseHttpPoller.prototype.onResponseCallback
// see inherited function BaseHttpPoller.prototype.onErrorCallback

HttpsPoller.prototype.handleRedirectResponse = function (res) {
    this.debug(this.getTime() + "ms - Got redirect response to " + this.target.href);
    var target = url.parse(res.headers.location);
    if (!target.protocol) {
        // relative location header. This is incorrect but tolerated
        this.target = url.parse('http://' + this.target.hostname + res.headers.location);
        this.poll(false);
        return;
    }
    switch (target.protocol) {
        case 'https:':
            this.target = target;
            this.poll(true);
            break;
        case 'http:':
            this.target = target;
            this.poll(false);
            break;
        default:
            this.request.abort();
            this.onErrorCallback({
                name: "WrongRedirectUrl",
                message: "Received redirection from https: to unsupported protocol " + target.protocol
            });
    }
    return;
};

module.exports = HttpsPoller;
<commit_msg>Change of access token regex format<commit_after>/**
 * Module dependencies.
 */

var util = require('util');
var https = require('https');
var http = require('http');
var url = require('url');
var fs = require('fs');
var ejs = require('ejs');
var qs = require('querystring');
var BaseHttpPoller = require('../http/baseHttpPoller');

// The http module lacks proxy support. Let's monkey-patch it.
require('../../proxy');

http.globalAgent.maxSockets = 10000;
https.globalAgent.maxSockets = 10000;

/**
 * HTTPS Poller, to check web pages served via SSL
 *
 * @param {Mixed} Poller Target (e.g. URL)
 * @param {Number} Poller timeout in milliseconds. Without response before this duration, the poller stops and executes the error callback.
 * @param {Function} Error/success callback
 * @api   public
 */
function HttpsPoller(target, timeout, callback) {
    HttpsPoller.super_.call(this, target, timeout, callback);
}

util.inherits(HttpsPoller, BaseHttpPoller);

HttpsPoller.type = 'https+oauth';

HttpsPoller.validateTarget = function (target) {
    return url.parse(target).protocol == 'https:';
};

getAccessToken = function (self, oauthEndpoint, params, credentials, onSuccess, onError) {
    try {
        var req = https.request(oauthEndpoint, function (res) {
          oauthEndpoint.agent = false;
          res.setEncoding('utf8');

            if (res.statusCode < 400) {
                body = "";
                res.on('data', function (chunk) {
                    body += chunk;
                });

                res.on('end', function () {
                    try {
                        var token;
                        if (typeof credentials != 'undefined' && credentials.response_type === 'token'){
                            token = res.headers.location.match(/(?:access_token=)([A-Za-z0-9-]+)/)[1];
                        }
                        else {
                            var jsonBody = JSON.parse(body);
                            token = jsonBody.access_token || jsonBody.accessToken;
                        }
                        onSuccess(self, token);
                    } catch (err) {
                        onError(self, {
                            name: "InvalidResponseData",
                            message: "oauth authentication failed, invalid data in response"
                        });
                    }
                });
            } else {
                req.abort();
                onError(self, {
                    name: "InvalidResponseStatus",
                    message: "oauth authentication failed, invalid status (" + res.statusCode + ") in response"
                });
            }
        });

        req.setTimeout(10000, function() {
          req.abort();
        });

        req.on('error', function (err) {
            onError(self, err);
        });
        if (typeof params != 'undefined') {
            req.write(qs.stringify(params), "utf-8");
        } else if (typeof credentials != 'undefined') {
            if (credentials.response_type || credentials.grant_type ) {
                req.write(qs.stringify(credentials), "utf-8");
            }
            else {
                req.write(JSON.stringify(credentials), "utf-8");
            }
        }
        req.end();
    } catch (err) {
        onError(self, {
            name: "UnknownError",
            message: "oauth authentication failed, an unknown error occured (" + err.message + ")"
        });
    }
}

/**
 * Launch the actual polling
 *
 * @api   public
 */
HttpsPoller.prototype.poll = function (secure) {
    getAccessToken(this, this.target.endpoint, this.target.params, this.target.credentials, function (self, token) {
        HttpsPoller.super_.prototype.poll.call(self);
        secure = typeof secure !== 'undefined' ? secure : true;
        try {
            var options = {
                agent: false,
                hostname: self.target.hostname,
                port: self.target.port,
                path: self.target.path,
                method: 'GET',
                headers: {
                    "Authorization": "Bearer " + token
                }
            };

            if (secure) {
                self.request = https.request(options, self.onResponseCallback.bind(self));
            } else {
                self.request = http.request(options, self.onResponseCallback.bind(self));
            }
        } catch (err) {
            return self.onErrorCallback(err);
        }
        self.request.on('error', self.onErrorCallback.bind(self));
        self.request.end();
    }, function (self, err) {
        HttpsPoller.super_.prototype.poll.call(self);
        return self.onErrorCallback(err);
    });
};

// see inherited function BaseHttpPoller.prototype.onResponseCallback
// see inherited function BaseHttpPoller.prototype.onErrorCallback

HttpsPoller.prototype.handleRedirectResponse = function (res) {
    this.debug(this.getTime() + "ms - Got redirect response to " + this.target.href);
    var target = url.parse(res.headers.location);
    if (!target.protocol) {
        // relative location header. This is incorrect but tolerated
        this.target = url.parse('http://' + this.target.hostname + res.headers.location);
        this.poll(false);
        return;
    }
    switch (target.protocol) {
        case 'https:':
            this.target = target;
            this.poll(true);
            break;
        case 'http:':
            this.target = target;
            this.poll(false);
            break;
        default:
            this.request.abort();
            this.onErrorCallback({
                name: "WrongRedirectUrl",
                message: "Received redirection from https: to unsupported protocol " + target.protocol
            });
    }
    return;
};

module.exports = HttpsPoller;
<|endoftext|>


<commit_before>/**
 * Module dependencies.
 */

var util = require('util');
var https = require('https');
var http = require('http');
var url = require('url');
var fs = require('fs');
var ejs = require('ejs');
var qs = require('querystring');
var BaseHttpPoller = require('../http/baseHttpPoller');

// The http module lacks proxy support. Let's monkey-patch it.
require('../../proxy');

/**
 * HTTPS Poller, to check web pages served via SSL
 *
 * @param {Mixed} Poller Target (e.g. URL)
 * @param {Number} Poller timeout in milliseconds. Without response before this duration, the poller stops and executes the error callback.
 * @param {Function} Error/success callback
 * @api   public
 */
function HttpsPoller(target, timeout, callback) {
    HttpsPoller.super_.call(this, target, timeout, callback);
}

util.inherits(HttpsPoller, BaseHttpPoller);

HttpsPoller.type = 'https+oauth';

HttpsPoller.validateTarget = function (target) {
    return url.parse(target).protocol == 'https:';
};

getAccessToken = function (self, oauthEndpoint, params, credentials, onSuccess, onError) {
    try {
        var req = https.request(oauthEndpoint, function (res) {
            res.setEncoding('utf8');

            if (res.statusCode < 400) {
                body = "";
                res.on('data', function (chunk) {
                    body += chunk;
                });

                res.on('end', function () {
                    try {
                        var token;
                        if (typeof credentials != 'undefined' && credentials.response_type === 'token'){
                            token = res.headers.location.match(/(?:access_token=)([A-Za-z0-9]+)/)[1];
                        }
                        else {
                            var jsonBody = JSON.parse(body);
                            token = jsonBody.access_token || jsonBody.accessToken;
                        }
                        onSuccess(self, token);
                    } catch (err) {
                        onError(self, {
                            name: "InvalidResponseData",
                            message: "oauth authentication failed, invalid data in response"
                        });
                    }
                });
            } else {
                onError(self, {
                    name: "InvalidResponseStatus",
                    message: "oauth authentication failed, invalid status (" + res.statusCode + ") in response"
                });
            }
        });

        req.on('error', function (err) {
            onError(self, err);
        });
        if (typeof params != 'undefined') {
            req.write(qs.stringify(params), "utf-8");
        } else if (typeof credentials != 'undefined') {
            if (credentials.response_type || credentials.grant_type ) {
                req.write(qs.stringify(credentials), "utf-8");
            }
            else {
                req.write(JSON.stringify(credentials), "utf-8");
            }
        }
        req.end();
    } catch (err) {
        onError(self, {
            name: "UnknownError",
            message: "oauth authentication failed, an unknown error occured (" + err.message + ")"
        });
    }
}

/**
 * Launch the actual polling
 *
 * @api   public
 */
HttpsPoller.prototype.poll = function (secure) {
    getAccessToken(this, this.target.endpoint, this.target.params, this.target.credentials, function (self, token) {
        HttpsPoller.super_.prototype.poll.call(self);
        secure = typeof secure !== 'undefined' ? secure : true;
        try {
            var options = {
                hostname: self.target.hostname,
                port: self.target.port,
                path: self.target.path,
                method: 'GET',
                headers: {
                    "Authorization": "Bearer " + token
                }
            };

            if (secure) {
                self.request = https.request(options, self.onResponseCallback.bind(self));
            } else {
                self.request = http.request(options, self.onResponseCallback.bind(self));
            }
        } catch (err) {
            return self.onErrorCallback(err);
        }
        self.request.on('error', self.onErrorCallback.bind(self));
        self.request.end();
    }, function (self, err) {
        HttpsPoller.super_.prototype.poll.call(self);
        return self.onErrorCallback(err);
    });
};

// see inherited function BaseHttpPoller.prototype.onResponseCallback
// see inherited function BaseHttpPoller.prototype.onErrorCallback

HttpsPoller.prototype.handleRedirectResponse = function (res) {
    this.debug(this.getTime() + "ms - Got redirect response to " + this.target.href);
    var target = url.parse(res.headers.location);
    if (!target.protocol) {
        // relative location header. This is incorrect but tolerated
        this.target = url.parse('http://' + this.target.hostname + res.headers.location);
        this.poll(false);
        return;
    }
    switch (target.protocol) {
        case 'https:':
            this.target = target;
            this.poll(true);
            break;
        case 'http:':
            this.target = target;
            this.poll(false);
            break;
        default:
            this.request.abort();
            this.onErrorCallback({
                name: "WrongRedirectUrl",
                message: "Received redirection from https: to unsupported protocol " + target.protocol
            });
    }
    return;
};

module.exports = HttpsPoller;
<commit_msg>connections did not get freed upon errors which caused uptime checks to freeze<commit_after>/**
 * Module dependencies.
 */

var util = require('util');
var https = require('https');
var http = require('http');
var url = require('url');
var fs = require('fs');
var ejs = require('ejs');
var qs = require('querystring');
var BaseHttpPoller = require('../http/baseHttpPoller');

// The http module lacks proxy support. Let's monkey-patch it.
require('../../proxy');

/**
 * HTTPS Poller, to check web pages served via SSL
 *
 * @param {Mixed} Poller Target (e.g. URL)
 * @param {Number} Poller timeout in milliseconds. Without response before this duration, the poller stops and executes the error callback.
 * @param {Function} Error/success callback
 * @api   public
 */
function HttpsPoller(target, timeout, callback) {
    HttpsPoller.super_.call(this, target, timeout, callback);
}

util.inherits(HttpsPoller, BaseHttpPoller);

HttpsPoller.type = 'https+oauth';

HttpsPoller.validateTarget = function (target) {
    return url.parse(target).protocol == 'https:';
};

getAccessToken = function (self, oauthEndpoint, params, credentials, onSuccess, onError) {
    try {
        var req = https.request(oauthEndpoint, function (res) {
            res.setEncoding('utf8');

            if (res.statusCode < 400) {
                body = "";
                res.on('data', function (chunk) {
                    body += chunk;
                });

                res.on('end', function () {
                    try {
                        var token;
                        if (typeof credentials != 'undefined' && credentials.response_type === 'token'){
                            token = res.headers.location.match(/(?:access_token=)([A-Za-z0-9]+)/)[1];
                        }
                        else {
                            var jsonBody = JSON.parse(body);
                            token = jsonBody.access_token || jsonBody.accessToken;
                        }
                        onSuccess(self, token);
                    } catch (err) {
                        onError(self, {
                            name: "InvalidResponseData",
                            message: "oauth authentication failed, invalid data in response"
                        });
                    }
                });
            } else {
                req.abort();
                onError(self, {
                    name: "InvalidResponseStatus",
                    message: "oauth authentication failed, invalid status (" + res.statusCode + ") in response"
                });
            }
        });

        req.setTimeout(10000, function() {
          req.abort();
        });

        req.on('error', function (err) {
            onError(self, err);
        });
        if (typeof params != 'undefined') {
            req.write(qs.stringify(params), "utf-8");
        } else if (typeof credentials != 'undefined') {
            if (credentials.response_type || credentials.grant_type ) {
                req.write(qs.stringify(credentials), "utf-8");
            }
            else {
                req.write(JSON.stringify(credentials), "utf-8");
            }
        }
        req.end();
    } catch (err) {
        onError(self, {
            name: "UnknownError",
            message: "oauth authentication failed, an unknown error occured (" + err.message + ")"
        });
    }
}

/**
 * Launch the actual polling
 *
 * @api   public
 */
HttpsPoller.prototype.poll = function (secure) {
    getAccessToken(this, this.target.endpoint, this.target.params, this.target.credentials, function (self, token) {
        HttpsPoller.super_.prototype.poll.call(self);
        secure = typeof secure !== 'undefined' ? secure : true;
        try {
            var options = {
                hostname: self.target.hostname,
                port: self.target.port,
                path: self.target.path,
                method: 'GET',
                headers: {
                    "Authorization": "Bearer " + token
                }
            };

            if (secure) {
                self.request = https.request(options, self.onResponseCallback.bind(self));
            } else {
                self.request = http.request(options, self.onResponseCallback.bind(self));
            }
        } catch (err) {
            return self.onErrorCallback(err);
        }
        self.request.on('error', self.onErrorCallback.bind(self));
        self.request.end();
    }, function (self, err) {
        HttpsPoller.super_.prototype.poll.call(self);
        return self.onErrorCallback(err);
    });
};

// see inherited function BaseHttpPoller.prototype.onResponseCallback
// see inherited function BaseHttpPoller.prototype.onErrorCallback

HttpsPoller.prototype.handleRedirectResponse = function (res) {
    this.debug(this.getTime() + "ms - Got redirect response to " + this.target.href);
    var target = url.parse(res.headers.location);
    if (!target.protocol) {
        // relative location header. This is incorrect but tolerated
        this.target = url.parse('http://' + this.target.hostname + res.headers.location);
        this.poll(false);
        return;
    }
    switch (target.protocol) {
        case 'https:':
            this.target = target;
            this.poll(true);
            break;
        case 'http:':
            this.target = target;
            this.poll(false);
            break;
        default:
            this.request.abort();
            this.onErrorCallback({
                name: "WrongRedirectUrl",
                message: "Received redirection from https: to unsupported protocol " + target.protocol
            });
    }
    return;
};

module.exports = HttpsPoller;
<|endoftext|>


<commit_before>/**
 * @author mrdoob / http://mrdoob.com/
 */

THREE.Face4 = function ( a, b, c, d, normal, color, materialIndex ) {

	return new THREE.Face3( a, b, c, normal, color, materialIndex );

};
<commit_msg>Added warning message in Face4 as suggested by @icannotfly in #3663.<commit_after>/**
 * @author mrdoob / http://mrdoob.com/
 */

THREE.Face4 = function ( a, b, c, d, normal, color, materialIndex ) {

	console.warn( 'THREE.Face4 has been removed. A THREE.Face3 will be created instead.')

	return new THREE.Face3( a, b, c, normal, color, materialIndex );

};
<|endoftext|>


<commit_before>/**
 * power-assert.js - Empower your assertions
 *
 * https://github.com/twada/power-assert.js
 *
 * Copyright (c) 2013 Takuto Wada
 * Licensed under the MIT license.
 *   https://raw.github.com/twada/power-assert.js/master/MIT-LICENSE.txt
 */
(function (root, factory) {
    'use strict';

    if (typeof define === 'function' && define.amd) {
        define(['./power-assert-core'], factory);
    } else if (typeof exports === 'object') {
        factory(require('./power-assert-core'));
    } else {
        factory(root._pa_);
    }
}(this, function (powerAssert) {
    'use strict';

    var row = function (numCols, initial) {
        var row = [], i;
        for(i = 0; i < numCols; i += 1) {
            row[i] = initial;
        }
        return row;
    };

    var newRowFor = function (line) {
        return row(line.length, ' ');
    };

    var createBuffer = function (offset, content) {
        var buffers = [], i;
        for (i = 0; i <= offset; i += 1) {
            buffers.push(newRowFor(content));
        }
        return buffers;
    };

    var formatLines = function (data, content, offset, dumper) {
        if (data.length === 0) {
            return [];
        }
        var buffers = createBuffer(offset, content),
            depth = 0,
            prev;
        data.forEach(function (cap) {
            var val = dumper(cap.value),
                bufOffset,
                i, j;
            if (typeof prev !== 'undefined' && prev.location.start.column <= cap.location.start.column + val.length) {
                depth += 1;
                buffers.push(newRowFor(content));
            }
            bufOffset = depth + offset;
            for (i = 0; i < bufOffset; i += 1) {
                buffers[i].splice(cap.location.start.column, 1, '|');
            }
            for (j = 0; j < val.length; j += 1) {
                buffers[bufOffset].splice(cap.location.start.column + j, 1, val.charAt(j));
            }
            prev = cap;
        });
        return buffers;
    };

    var rightToLeft = function (a, b) {
        return b.location.start.column - a.location.start.column;
    };

    powerAssert.on('assert.fail', function (context) {
        var content = context.content,
            location = context.location,
            target = context.idents.concat(context.funcalls).concat(context.binaries);
        target.sort(rightToLeft);
        powerAssert.puts('# at line: ' + location.start.line);
        powerAssert.puts(content);
        formatLines(target, content, 1, powerAssert.dump).forEach(function (buffer) {
            powerAssert.puts(buffer.join(''));
        });
        powerAssert.puts('');
    });
}));
<commit_msg>Refactor more<commit_after>/**
 * power-assert.js - Empower your assertions
 *
 * https://github.com/twada/power-assert.js
 *
 * Copyright (c) 2013 Takuto Wada
 * Licensed under the MIT license.
 *   https://raw.github.com/twada/power-assert.js/master/MIT-LICENSE.txt
 */
(function (root, factory) {
    'use strict';

    if (typeof define === 'function' && define.amd) {
        define(['./power-assert-core'], factory);
    } else if (typeof exports === 'object') {
        factory(require('./power-assert-core'));
    } else {
        factory(root._pa_);
    }
}(this, function (powerAssert) {
    'use strict';

    var row = function (numCols, initial) {
        var row = [], i;
        for(i = 0; i < numCols; i += 1) {
            row[i] = initial;
        }
        return row;
    };

    var newRowFor = function (assertionLine) {
        return row(assertionLine.length, ' ');
    };

    var createBuffer = function (offset, assertionLine) {
        var buffers = [], i;
        for (i = 0; i <= offset; i += 1) {
            buffers.push(newRowFor(assertionLine));
        }
        return buffers;
    };

    var interleaves = function (prevCapturing, nextCaputuring, val) {
        return (typeof prevCapturing !== 'undefined') && prevCapturing.location.start.column <= (nextCaputuring.location.start.column + val.length);
    };

    var formatLines = function (capturedEvents, assertionLine, offset, dumper) {
        if (capturedEvents.length === 0) {
            return [];
        }
        var buffers = createBuffer(offset, assertionLine),
            prevCaptured;
        capturedEvents.forEach(function (captured) {
            var val = dumper(captured.value),
                lastLineIndex,
                i, j;
            if (interleaves(prevCaptured, captured, val)) {
                buffers.push(newRowFor(assertionLine));
            }
            lastLineIndex = buffers.length - 1;
            for (i = 0; i < lastLineIndex; i += 1) {
                buffers[i].splice(captured.location.start.column, 1, '|');
            }
            for (j = 0; j < val.length; j += 1) {
                buffers[lastLineIndex].splice(captured.location.start.column + j, 1, val.charAt(j));
            }
            prevCaptured = captured;
        });
        return buffers;
    };

    var rightToLeft = function (a, b) {
        return b.location.start.column - a.location.start.column;
    };

    powerAssert.on('assert.fail', function (context) {
        var line = context.content,
            location = context.location,
            target = context.idents.concat(context.funcalls).concat(context.binaries);
        target.sort(rightToLeft);
        powerAssert.puts('# at line: ' + location.start.line);
        powerAssert.puts(line);
        formatLines(target, line, 1, powerAssert.dump).forEach(function (buffer) {
            powerAssert.puts(buffer.join(''));
        });
        powerAssert.puts('');
    });
}));
<|endoftext|>