<commit_before>(function () {
  ///
  /// LOGIN HANDLERS
  ///

  Meteor.methods({
    // @returns {Object|null}
    //   If successful, returns {token: reconnectToken, id: userId}
    //   If unsuccessful (for example, if the user closed the oauth login popup),
    //     returns null
    login: function(options) {
      var result = tryAllLoginHandlers(options);
      if (result !== null)
        this.setUserId(result.id);
      return result;
    },

    logout: function() {
      this.setUserId(null);
    }
  });

  Accounts._loginHandlers = [];

  // Try all of the registered login handlers until one of them
  // doesn't return `undefined` (NOT null), meaning it handled this
  // call to `login`. Return that return value.
  var tryAllLoginHandlers = function (options) {
    var result = undefined;

    _.find(Accounts._loginHandlers, function(handler) {

      var maybeResult = handler(options);
      if (maybeResult !== undefined) {
        result = maybeResult;
        return true;
      } else {
        return false;
      }
    });

    if (result === undefined) {
      throw new Meteor.Error(400, "Unrecognized options for login request");
    } else {
      return result;
    }
  };

  // @param handler {Function} A function that receives an options object
  // (as passed as an argument to the `login` method) and returns one of:
  // - `undefined`, meaning don't handle;
  // - `null`, meaning the user didn't actually log in;
  // - {id: userId, accessToken: *}, if the user logged in successfully.
  Accounts.registerLoginHandler = function(handler) {
    Accounts._loginHandlers.push(handler);
  };

  // support reconnecting using a meteor login token
  Accounts._generateStampedLoginToken = function () {
    return {token: Meteor.uuid(), when: +(new Date)};
  };

  Accounts.registerLoginHandler(function(options) {
    if (options.resume) {
      var user = Meteor.users.findOne(
        {"services.resume.loginTokens.token": options.resume});
      if (!user)
        throw new Meteor.Error(403, "Couldn't find login token");

      return {
        token: options.resume,
        id: user._id
      };
    } else {
      return undefined;
    }
  });


  ///
  /// CURRENT USER
  ///
  Meteor.userId = function () {
    // This function only works if called inside a method. In theory, it
    // could also be called from publish statements, since they also
    // have a userId associated with them. However, given that publish
    // functions aren't reactive, using any of the infomation from
    // Meteor.user() in a publish function will always use the value
    // from when the function first runs. This is likely not what the
    // user expects. The way to make this work in a publish is to do
    // Meteor.find(this.userId()).observe and recompute when the user
    // record changes.
    var currentInvocation = Meteor._CurrentInvocation.get();
    if (!currentInvocation)
      throw new Error("Meteor.userId can only be invoked in method calls. Use this.userId in publish functions.");
    return currentInvocation.userId;
  };

  Meteor.user = function () {
    var userId = Meteor.userId();
    if (!userId)
      return null;
    return Meteor.users.findOne(userId);
  };

  ///
  /// CREATE USER HOOKS
  ///
  var onCreateUserHook = null;
  Accounts.onCreateUser = function (func) {
    if (onCreateUserHook)
      throw new Error("Can only call onCreateUser once");
    else
      onCreateUserHook = func;
  };

  // XXX see comment on Accounts.createUser in passwords_server about adding a
  // second "server options" argument.
  var defaultCreateUserHook = function (options, user) {
    if (options.profile)
      user.profile = options.profile;
    return user;
  };
  Accounts.insertUserDoc = function (options, user) {
    // add created at timestamp (and protect passed in user object from
    // modification)
    user = _.extend({createdAt: +(new Date)}, user);

    var fullUser;

    if (onCreateUserHook) {
      fullUser = onCreateUserHook(options, user);

      // This is *not* part of the API. We need this because we can't isolate
      // the global server environment between tests, meaning we can't test
      // both having a create user hook set and not having one set.
      if (fullUser === 'TEST DEFAULT HOOK')
        fullUser = defaultCreateUserHook(options, user);
    } else {
      fullUser = defaultCreateUserHook(options, user);
    }

    _.each(validateNewUserHooks, function (hook) {
      if (!hook(fullUser))
        throw new Meteor.Error(403, "User validation failed");
    });

    var result = {};
    if (options.generateLoginToken) {
      var stampedToken = Accounts._generateStampedLoginToken();
      result.token = stampedToken.token;
      Meteor._ensure(fullUser, 'services', 'resume');
      if (_.has(fullUser.services.resume, 'loginTokens'))
        fullUser.services.resume.loginTokens.push(stampedToken);
      else
        fullUser.services.resume.loginTokens = [stampedToken];
    }

    try {
      result.id = Meteor.users.insert(fullUser);
    } catch (e) {<commit_msg>Generate login token before onCreateUser and validation.<commit_after>(function () {
  ///
  /// LOGIN HANDLERS
  ///

  Meteor.methods({
    // @returns {Object|null}
    //   If successful, returns {token: reconnectToken, id: userId}
    //   If unsuccessful (for example, if the user closed the oauth login popup),
    //     returns null
    login: function(options) {
      var result = tryAllLoginHandlers(options);
      if (result !== null)
        this.setUserId(result.id);
      return result;
    },

    logout: function() {
      this.setUserId(null);
    }
  });

  Accounts._loginHandlers = [];

  // Try all of the registered login handlers until one of them
  // doesn't return `undefined` (NOT null), meaning it handled this
  // call to `login`. Return that return value.
  var tryAllLoginHandlers = function (options) {
    var result = undefined;

    _.find(Accounts._loginHandlers, function(handler) {

      var maybeResult = handler(options);
      if (maybeResult !== undefined) {
        result = maybeResult;
        return true;
      } else {
        return false;
      }
    });

    if (result === undefined) {
      throw new Meteor.Error(400, "Unrecognized options for login request");
    } else {
      return result;
    }
  };

  // @param handler {Function} A function that receives an options object
  // (as passed as an argument to the `login` method) and returns one of:
  // - `undefined`, meaning don't handle;
  // - `null`, meaning the user didn't actually log in;
  // - {id: userId, accessToken: *}, if the user logged in successfully.
  Accounts.registerLoginHandler = function(handler) {
    Accounts._loginHandlers.push(handler);
  };

  // support reconnecting using a meteor login token
  Accounts._generateStampedLoginToken = function () {
    return {token: Meteor.uuid(), when: +(new Date)};
  };

  Accounts.registerLoginHandler(function(options) {
    if (options.resume) {
      var user = Meteor.users.findOne(
        {"services.resume.loginTokens.token": options.resume});
      if (!user)
        throw new Meteor.Error(403, "Couldn't find login token");

      return {
        token: options.resume,
        id: user._id
      };
    } else {
      return undefined;
    }
  });


  ///
  /// CURRENT USER
  ///
  Meteor.userId = function () {
    // This function only works if called inside a method. In theory, it
    // could also be called from publish statements, since they also
    // have a userId associated with them. However, given that publish
    // functions aren't reactive, using any of the infomation from
    // Meteor.user() in a publish function will always use the value
    // from when the function first runs. This is likely not what the
    // user expects. The way to make this work in a publish is to do
    // Meteor.find(this.userId()).observe and recompute when the user
    // record changes.
    var currentInvocation = Meteor._CurrentInvocation.get();
    if (!currentInvocation)
      throw new Error("Meteor.userId can only be invoked in method calls. Use this.userId in publish functions.");
    return currentInvocation.userId;
  };

  Meteor.user = function () {
    var userId = Meteor.userId();
    if (!userId)
      return null;
    return Meteor.users.findOne(userId);
  };

  ///
  /// CREATE USER HOOKS
  ///
  var onCreateUserHook = null;
  Accounts.onCreateUser = function (func) {
    if (onCreateUserHook)
      throw new Error("Can only call onCreateUser once");
    else
      onCreateUserHook = func;
  };

  // XXX see comment on Accounts.createUser in passwords_server about adding a
  // second "server options" argument.
  var defaultCreateUserHook = function (options, user) {
    if (options.profile)
      user.profile = options.profile;
    return user;
  };
  Accounts.insertUserDoc = function (options, user) {
    // add created at timestamp (and protect passed in user object from
    // modification)
    user = _.extend({createdAt: +(new Date)}, user);

    var result = {};
    if (options.generateLoginToken) {
      var stampedToken = Accounts._generateStampedLoginToken();
      result.token = stampedToken.token;
      Meteor._ensure(user, 'services', 'resume');
      if (_.has(user.services.resume, 'loginTokens'))
        user.services.resume.loginTokens.push(stampedToken);
      else
        user.services.resume.loginTokens = [stampedToken];
    }

    var fullUser;
    if (onCreateUserHook) {
      fullUser = onCreateUserHook(options, user);

      // This is *not* part of the API. We need this because we can't isolate
      // the global server environment between tests, meaning we can't test
      // both having a create user hook set and not having one set.
      if (fullUser === 'TEST DEFAULT HOOK')
        fullUser = defaultCreateUserHook(options, user);
    } else {
      fullUser = defaultCreateUserHook(options, user);
    }

    _.each(validateNewUserHooks, function (hook) {
      if (!hook(fullUser))
        throw new Meteor.Error(403, "User validation failed");
    });

    try {
      result.id = Meteor.users.insert(fullUser);
    } catch (e) {
{'fraction_non_alphanumeric': 0.11081716637272193, 'fraction_numerical': 0.001763668430335097, 'mean_word_length': 2.688832670762559, 'pattern_counts': {'":': 2, '<': 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': '3820307', 'n_tokens_mistral': 2964, 'n_tokens_neox': 2879, 'n_words': 948}