<commit_before>var parse = require('url-parse');
var auth0 = require('auth0-js');
var getAgent = require('./agent');
var crypto = require('./crypto');
var session = require('./session');

var generateProofKey = crypto.generateProofKey;
var generateState = crypto.generateState;

session.clean();

function getOS() {
  var userAgent = navigator.userAgent;
  if (/android/i.test(userAgent)) {
    return 'android';
  }

  if (/iPad|iPhone|iPod/.test(userAgent) && !window.MSStream) {
    return 'ios';
  }
}

function CordovaAuth(options) {
  this.clientId = options.clientId;
  this.domain = options.domain;
  this.redirectUri = options.packageIdentifier + '://' + options.domain + '/cordova/' + options.packageIdentifier + '/callback';
  this.client = new auth0.Authentication({
    clientID: this.clientId,
    domain: this.domain,
    _telemetryInfo: {
      version: CordovaAuth.version,
      name: 'auth0-cordova'
    }
  });
}

CordovaAuth.prototype.authorize = function (parameters, callback) {
  if (typeof parameters === 'function') {
    parameters = callback;
    parameters = {};
  }

  if (!callback || typeof callback !== 'function') {
    throw new Error('callback not specified or is not a function');
  }

  var self = this;

  getAgent(function (err, agent) {
    if (err) {
      return callback(err);
    }

    var keys = generateProofKey();
    var client = self.client;
    var redirectUri = self.redirectUri;
    var requestState = parameters.state || generateState();

    parameters.state = requestState;

    var params = Object.assign({}, parameters, {
      code_challenge_method: 'S256',
      responseType: 'code',
      redirectUri: redirectUri,
      code_challenge: keys.codeChallenge
    });

    var url = client.buildAuthorizeUrl(params);

    agent.open(url, function (error, result) {
      if (error != null) {
        session.clean();
        return callback(error);
      }

      if (result.event === 'closed' && getOS() === 'ios') {
        session.clean();
        return callback(new Error('user canceled'));
      }

      if (result.event !== 'loaded') {
        // Ignore any other events.
        return;
      }

      session.start(function (sessionError, redirectUrl) {
        if (sessionError != null) {
          callback(sessionError);
          return true;
        }

        if (redirectUrl.indexOf(redirectUri) === -1) {
          return false;
        }

        if (!redirectUrl || typeof redirectUrl !== 'string') {
          callback(new Error('url must be a string'));
          return true;
        }

        var response = parse(redirectUrl, true).query;
        if (response.error) {
          callback(new Error(response.error_description || response.error));
          return true;
        }

        var responseState = response.state;
        if (responseState !== requestState) {
          callback(new Error('Response state does not match expected state'));
          return true;
        }

        var code = response.code;
        var verifier = keys.codeVerifier;
        client.oauthToken({
          code_verifier: verifier,
          grantType: 'authorization_code',
          redirectUri: redirectUri,
          code: code
        }, function (exchangeError, exchangeResult) {
          agent.close();
          if (exchangeError) {
            return callback(exchangeError);
          }
          return callback(null, exchangeResult);
        });

        return true;
      });
    });
  });
};

CordovaAuth.onRedirectUri = function (url) {
  session.onRedirectUri(url);
};

CordovaAuth.version = '0.1.0';

module.exports = CordovaAuth;<commit_msg>Improve telemetry info<commit_after>var parse = require('url-parse');
var auth0 = require('auth0-js');
var getAgent = require('./agent');
var crypto = require('./crypto');
var session = require('./session');
var getOS = require('./utils').getOS;
var version = require('./version').raw;

var generateProofKey = crypto.generateProofKey;
var generateState = crypto.generateState;

session.clean();

var telemetry = {
  version: version,
  name: 'auth0-cordova',
  lib_version: auth0.version
};

function CordovaAuth(options) {
  this.clientId = options.clientId;
  this.domain = options.domain;
  this.redirectUri = options.packageIdentifier + '://' + options.domain + '/cordova/' + options.packageIdentifier + '/callback';
  this.client = new auth0.Authentication({
    clientID: this.clientId,
    domain: this.domain,
    _telemetryInfo: telemetry
  });
}

CordovaAuth.prototype.authorize = function (parameters, callback) {
  if (typeof parameters === 'function') {
    parameters = callback;
    parameters = {};
  }

  if (!callback || typeof callback !== 'function') {
    throw new Error('callback not specified or is not a function');
  }

  var self = this;

  getAgent(function (err, agent) {
    if (err) {
      return callback(err);
    }

    var keys = generateProofKey();
    var client = self.client;
    var redirectUri = self.redirectUri;
    var requestState = parameters.state || generateState();

    parameters.state = requestState;

    var params = Object.assign({}, parameters, {
      code_challenge_method: 'S256',
      responseType: 'code',
      redirectUri: redirectUri,
      code_challenge: keys.codeChallenge
    });

    var url = client.buildAuthorizeUrl(params);

    agent.open(url, function (error, result) {
      if (error != null) {
        session.clean();
        return callback(error);
      }

      if (result.event === 'closed' && getOS() === 'ios') {
        session.clean();
        return callback(new Error('user canceled'));
      }

      if (result.event !== 'loaded') {
        // Ignore any other events.
        return;
      }

      session.start(function (sessionError, redirectUrl) {
        if (sessionError != null) {
          callback(sessionError);
          return true;
        }

        if (redirectUrl.indexOf(redirectUri) === -1) {
          return false;
        }

        if (!redirectUrl || typeof redirectUrl !== 'string') {
          callback(new Error('url must be a string'));
          return true;
        }

        var response = parse(redirectUrl, true).query;
        if (response.error) {
          callback(new Error(response.error_description || response.error));
          return true;
        }

        var responseState = response.state;
        if (responseState !== requestState) {
          callback(new Error('Response state does not match expected state'));
          return true;
        }

        var code = response.code;
        var verifier = keys.codeVerifier;
        client.oauthToken({
          code_verifier: verifier,
          grantType: 'authorization_code',
          redirectUri: redirectUri,
          code: code
        }, function (exchangeError, exchangeResult) {
          agent.close();
          if (exchangeError) {
            return callback(exchangeError);
          }
          return callback(null, exchangeResult);
        });

        return true;
      });
    });
  });
};

CordovaAuth.onRedirectUri = function (url) {
  session.onRedirectUri(url);
};

CordovaAuth.version = version;

module.exports = CordovaAuth;
{'fraction_non_alphanumeric': 0.12933314770987053, 'fraction_numerical': 0.0027843519420854795, 'mean_word_length': 2.552917903066271, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3568813', 'n_tokens_mistral': 2034, 'n_tokens_neox': 1971, 'n_words': 486}