public function testResetPassword()
 {
     $user = new User();
     //generate a token that expires
     $token = $user->generateResetPasswordToken($this->valid_test_email);
     //throw an exception when an invalid token is used
     $wrongToken = Utils::generateRandomString(20);
     $this->throwResetPasswordException($wrongToken);
     //generate a token that expires using a negative timestamp so that the tokens expiry date is before the current time
     $expiredToken = $user->generateResetPasswordToken($this->valid_test_email, null, true, -(4 * 24 * 3600));
     $this->throwResetPasswordException($expiredToken);
     //reset the password with a valid token
     $newPassword = User::generateRandomPassword();
     $response = $user->resetPassword($this->valid_test_email, $newPassword, $token);
     $this->assertTrue($response);
     //authenticate with new password
     $response = $user->authenticate($this->valid_test_email, $newPassword);
     $this->assertNotEmpty($response);
     //try to use the same token again even when it has expired
     $this->throwResetPasswordException($token);
 }
 /**
  * @param int $user_id
  * @param int $tokenLength
  * @param int $expires
  * @param boolean $expiry
  * @return string
  * @throws ResetPasswordException
  */
 public function generateToken($user_id, $tokenLength, $expires, $expiry)
 {
     if ($tokenLength > self::MAX_TOKEN_LENGTH) {
         throw new ResetPasswordException(sprintf(ErrorMessages::RESET_PASSWORD_TOKEN_TOO_LONG, UserPasswordReset::MAX_TOKEN_LENGTH));
     }
     if ($tokenLength < self::MIN_TOKEN_LENGTH) {
         throw new ResetPasswordException(sprintf(ErrorMessages::RESET_PASSWORD_TOKEN_TOO_SHORT, UserPasswordReset::MIN_TOKEN_LENGTH));
     }
     $tokenLength = $tokenLength - 10;
     //append a timestamp
     $token = Utils::generateRandomString($tokenLength, false);
     if ($this->tokenExists($token)) {
         return $this->generateToken($user_id, $tokenLength, $expires, $expiry);
     }
     $token = $token . time();
     $this->setUserId($user_id);
     $this->setExpires((int) $expires);
     $this->setDateOfExpiry($expires ? time() + $expiry : null);
     $this->setToken($token);
     $this->setDateRequested(date("Y-m-d H:i:s"));
     if (!$this->create()) {
         throw new ResetPasswordException(ErrorMessages::RESET_PASSWORD_FAILED);
     }
     return $token;
 }