<commit_before>var crypto = Npm.require('crypto');

///
/// 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 = DDP._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);
};


///
/// LOGIN HOOKS
///

// Exceptions inside the hook callback are passed up to us.
var validateLoginHook = new Hook();

// Callback exceptions are printed with Meteor._debug and ignored.
var onLoginHook = new Hook({
  debugPrintExceptions: "onLogin callback"
});
var onLoginFailureHook = new Hook({
  debugPrintExceptions: "onLoginFailure callback"
});

Accounts.validateLoginAttempt = function (func) {
  return validateLoginHook.register(func);
};

Accounts.onLogin = function (func) {
  return onLoginHook.register(func);
};

Accounts.onLoginFailure = function (func) {
  return onLoginFailureHook.register(func);
};


// Give each login hook callback a fresh cloned copy of the attempt
// object, but don't clone the connection.
//
var cloneAttemptWithConnection = function (connection, attempt) {
  var clonedAttempt = EJSON.clone(attempt);
  clonedAttempt.connection = connection;
  return clonedAttempt;
};

var validateLogin = function (connection, attempt) {
  validateLoginHook.each(function (callback) {
    var ret;
    try {
      ret = callback(cloneAttemptWithConnection(connection, attempt));
    }
    catch (e) {
      attempt.allowed = false;
      attempt.error = e;
      return true;
    }
    if (! ret) {
      attempt.allowed = false;
      attempt.error = new Meteor.Error(403, "Login forbidden");
    }
    return true;
  });
};


var successfulLogin = function (connection, attempt) {
  onLoginHook.each(function (callback) {
    callback(cloneAttemptWithConnection(connection, attempt));
    return true;
  });
};

var failedLogin = function (connection, attempt) {
  onLoginFailureHook.each(function (callback) {
    callback(cloneAttemptWithConnection(connection, attempt));
    return true;
  });
};


///<commit_msg>Don't override specific error messages with generic ones.<commit_after>var crypto = Npm.require('crypto');

///
/// 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 = DDP._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);
};


///
/// LOGIN HOOKS
///

// Exceptions inside the hook callback are passed up to us.
var validateLoginHook = new Hook();

// Callback exceptions are printed with Meteor._debug and ignored.
var onLoginHook = new Hook({
  debugPrintExceptions: "onLogin callback"
});
var onLoginFailureHook = new Hook({
  debugPrintExceptions: "onLoginFailure callback"
});

Accounts.validateLoginAttempt = function (func) {
  return validateLoginHook.register(func);
};

Accounts.onLogin = function (func) {
  return onLoginHook.register(func);
};

Accounts.onLoginFailure = function (func) {
  return onLoginFailureHook.register(func);
};


// Give each login hook callback a fresh cloned copy of the attempt
// object, but don't clone the connection.
//
var cloneAttemptWithConnection = function (connection, attempt) {
  var clonedAttempt = EJSON.clone(attempt);
  clonedAttempt.connection = connection;
  return clonedAttempt;
};

var validateLogin = function (connection, attempt) {
  validateLoginHook.each(function (callback) {
    var ret;
    try {
      ret = callback(cloneAttemptWithConnection(connection, attempt));
    }
    catch (e) {
      attempt.allowed = false;
      // XXX this means the last thrown error overrides previous error
      // messages. Maybe this is surprising to users and we should make
      // overriding errors more explicit. (see
      // https://github.com/meteor/meteor/issues/1960)
      attempt.error = e;
      return true;
    }
    if (! ret) {
      attempt.allowed = false;
      // don't override a specific error provided by a previous
      // validator or the initial attempt (eg "incorrect password").
      if (!attempt.error)
        attempt.error = new Meteor.Error(403, "Login forbidden");
    }
    return true;
  });
};


var successfulLogin = function (connection, attempt) {
  onLoginHook.each(function (callback) {
    callback(cloneAttemptWithConnection(connection, attempt));
    return true;
  });
};

var failedLogin = function (connection, attempt) {
  onLoginFailureHook.each(function (callback) {
    callback(cloneAttemptWithConnection(connection, attempt));
    return true;
  });
};


///
{'fraction_non_alphanumeric': 0.10606562810739145, 'fraction_numerical': 0.0016572754391779914, 'mean_word_length': 3.558157099697885, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 1, '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': '3094002', 'n_tokens_mistral': 1721, 'n_tokens_neox': 1666, 'n_words': 577}