resetPassword = async (token, newPassword) => {
  //check(token, String);
  //check(newPassword, passwordValidator);
  // Find the user with this token
  const user = await Meteor.users.findOne(
    { 'services.password.reset.token': token },
    {
      fields: {
        services: 1,
        emails: 1,
      },
    }
  );
  if (!user) {
    throw new Error('Token expired or invalid');
  }
  const userId = user._id;
  // check the token validity
  const { when, reason, email } = user.services.password.reset;
  let tokenLifetimeMs = Accounts._getPasswordResetTokenLifetimeMs();
  if (reason === 'enroll') {
    tokenLifetimeMs = Accounts._getPasswordEnrollTokenLifetimeMs();
  }
  const currentTimeMs = Date.now();
  if (currentTimeMs - when > tokenLifetimeMs) throw new Error('Token expired');
  if (!pluckAddresses(user.emails).includes(email))
    return {
      userId,
      error: new Error('Token has invalid email address'),
    };

  // Prepare rollback in case of failure
  // => this.connection is not defined
  // const oldToken = Accounts._getLoginToken(this.connection.id);
  // Accounts._setLoginToken(user._id, this.connection, null);
  // const resetToOldToken = () => Accounts._setLoginToken(user._id, this.connection, oldToken);

  // Meteor had a more complex logic here for some reason
  // we just reuse the setPassword logic
  //const hashed = hashPassword(newPassword);
  // NOTE: We're about to invalidate tokens on the user, who we might be
  // logged in as. Make sure to avoid logging ourselves out if this
  // happens. But also make sure not to leave the connection in a state
  // of having a bad token set if things fail.
  await setPassword(userId, newPassword);

  // Update the user record by:
  // - Changing the password to the new one => done by setPassword
  // - Forgetting about the reset token that was just used
  // - Verifying their email, since they got the password reset via email.
  try {
    const affectedRecords = await Meteor.users.update(
      {
        _id: userId,
        'emails.address': email,
        'services.password.reset.token': token,
      },
      //{$set: {'services.password.bcrypt': hashed,
      //        'emails.$.verified': true},
      {
        $unset: { 'services.password.reset': 1, 'services.password.srp': 1 },
      }
    );
    if (affectedRecords !== 1) {
      return {
        userId: userId,
        error: new Meteor.Error('Invalid email'),
      };
    }
  } catch (err) {
    // resetToOldToken();
    throw err;
  }

  // Replace all valid login tokens with new ones (changing
  // password should invalidate existing sessions).
  Accounts._clearAllLoginTokens(userId);

  return { userId: userId };
}
For non connected user, need to parse the token
https://github.com/meteor/meteor/blob/devel/packages/accounts-password/password_server.js#L804
@param {*} userId
@param {*} newPassword