Page 1 of 1

Not Working When Correct Info is provided

Posted: Mon Dec 09, 2013 2:12 am
by Aleeious
I am trying to get my forgot password feature setup. However when correct info is entered ablank page is shown and the password isn't reset. If incorrect info is provided the message is shown. I want the message to be shown reguardless if correct info is provided or not unless an error occurs such as the database can't be contacted. I am posting my code in hopes someone can figure it out.
reset password function:

Code: Select all

/**
	* changes the users password 
	* @param $username username to check
	* @param $email user email tied to user
	* @return true if login is successful otherwise false
	*/
	public function resetPassword($username, $email)
	{
		// prepare the sql statement
		$statement = $this->db->prepare('SELECT salt FROM ' . TABLE_USERS . ' WHERE USERNAME = ? AND EMAIL = ? LIMIT 1');

		// bing the variables
		$statement->bind_param('ss', $username, $email);

		// if the statement executed successfully
		if ($statement->execute())
		{
			// get the number of results
			$statement->bind_result($resultsalt);

			// fetch the results
			$statement->fetch();
echo $resultsalt . "<br />";
			// if a result exists
			if($resultsalt)
			{
				// generate a new password
				$password = $this->generateRandomPassword(10);
echo $password . "<br />";
                // hash the password using the stored hash
                $passwordhash = $this->generateHash($password, $resultsalt);
echo $passwordhash . "<br />";
				// prepare the sql statement to change the password
				$statement = $this->db->prepare('UPDATE ' . TABLE_USERS . ' SET PASSWORD = ? WHERE USERNAME = ? AND EMAIL = ? LIMIT 1');

				// bing the variables
				$statement->bind_param('sss', $passwordhash, $username, $email);

				// if the statement executed successfully
				if ($statement->execute())
				{
					// get the number of results
					$statement->bind_result($result);

					// fetch the results
					$statement->fetch();

					// if a result exists
					if($result)
					{
						echo "New Password: " . $password . "<br />";
					}

                    // return success
					return true;
        		}
				else
				{
					// second sql statement didn't execute so return false
					return false;
				}
			}
			else
			{
				// the query was successful but the info was incorrect so return true
				return true;
			}
		}
		else
		{
			// first sql statement didn't execute so return false
			return false;
		}
	}
forgot password page:

Code: Select all

<?php

// disable display or error messages and log them instead
ini_set('error_reporting', E_ALL | E_STRICT);
ini_set('display_errors', 'Off');
ini_set('log_errors', 'On');
ini_set('error_log', '/logs/error_log');

// include smarty library
require('libs/Smarty.class.php');

// include database library
require_once('libs/Database.class.php');

// include user library
require_once('libs/User.class.php');

// create instance of smarty library
$smarty = new Smarty();

// set content header
header("Content-Type: " . USER_CONTENT_TYPE);

// if the form wasn't submited
if(!isset($_POST["submit"]))
{
	// display it
	$smarty->display('forgotpassword.tpl');
}
// otherwise the form was submitted
else
{
	// if the username is empty
	if(empty($_POST["username"]))
	{
		// so display an error stating the username is empty
		$smarty->assign('error', 'username is empty');

		// and display it
		$smarty->display('error.tpl');

		// and terminate
		exit;
	}
	// if the username is too short or too big
	elseif(strlen($_POST["username"]) < 4 || strlen($_POST["username"]) > 16)
	{
		// so display an error stating the username is empty
		$smarty->assign('error', 'username must be 4-16 characters long');

		// and display it
		$smarty->display('error.tpl');

		// and terminate
		exit;
	}
	// otherwise the username is filled in
	else
	{
		// so sanitize it
		$username = $_POST["username"];
	}

	// if the email is empty
	if(empty($_POST["email"]))
	{
		// so display an error stating the password is empty
		$smarty->assign('error', 'email is empty');

		// and display it
		$smarty->display('error.tpl');

		// and terminate
		exit;
	}
	// if the email is invalid
	elseif(!preg_match('/^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,3})$/', $_POST["email"]))
	{
		// so display an error stating the email is invalid
		$smarty->assign('error', 'the email address you entered is invalid');

		// and display it
		$smarty->display('error.tpl');

		// and terminate
		exit;
	}
	// otherwise the email is ok
	else
	{
		// so sanitize it
		$email = $_POST["email"];
	}

	// create instance of database class
	$database = new Database();

	// create instance of user class
	$user = new User($database);

	// check the users login info
	if(!$user->resetPassword($username, $email))
	{
		// otherwise display an error stating the the feature isn't implemented
		$smarty->assign('error', 'there was a problem contacting the database, please notify an admin');

		// display it
		$smarty->display('error.tpl');
		
	}
    else
    {
		// otherwise display an error stating the the feature isn't implemented
		$smarty->assign('error', 'if you provided correct info your password has been reset and an email has been sent with your new password');

		// display it
		$smarty->display('error.tpl');
	}
}

?>
Any assistance in this matter would be greatly appreciated.

Sincerely,

AleeiousMMO

Re: Not Working When Correct Info is provided

Posted: Mon Dec 09, 2013 6:54 am
by MikuzA
Hello,

I went through your code and it should not show a blank page unless an fatal error is triggered.

So I suspect that somewhere at the UPDATE of the new passwordhash it goes boom..

Have you checked logs?
Or have you executed that same stuff with display_errors 'On'?

Re: Not Working When Correct Info is provided

Posted: Sun Dec 22, 2013 12:57 am
by Aleeious
Seems I am getting errors and strange ones:
Notice: Use of undefined constant DATABASE_SERVER - assumed 'DATABASE_SERVER' in /home/aleeious/public_html/beta/config.php on line 4

Notice: Use of undefined constant DATABASE_USERNAME - assumed 'DATABASE_USERNAME' in /home/aleeious/public_html/beta/config.php on line 7

Notice: Use of undefined constant DATABASE_PASSWORD - assumed 'DATABASE_PASSWORD' in /home/aleeious/public_html/beta/config.php on line 10

Notice: Use of undefined constant DATABASE_NAME - assumed 'DATABASE_NAME' in /home/aleeious/public_html/beta/config.php on line 13

Notice: Use of undefined constant TABLE_PREFIX - assumed 'TABLE_PREFIX' in /home/aleeious/public_html/beta/config.php on line 16

Notice: Use of undefined constant TABLE_USERS - assumed 'TABLE_USERS' in /home/aleeious/public_html/beta/config.php on line 21

Notice: Use of undefined constant TABLE_SESSIONS - assumed 'TABLE_SESSIONS' in /home/aleeious/public_html/beta/config.php on line 24

Notice: Use of undefined constant USER_CONTENT_TYPE - assumed 'USER_CONTENT_TYPE' in /home/aleeious/public_html/beta/config.php on line 28

Warning: Cannot modify header information - headers already sent by (output started at /home/aleeious/public_html/beta/config.php:4) in /home/aleeious/public_html/beta/forgotpassword.php on line 25
Heres my cofig.php file:

Code: Select all

<?php

// mysql server host
define(DATABASE_SERVER, "localhost");

// mysql server username
define(DATABASE_USERNAME, "");

// mysql server password
define(DATABASE_PASSWORD, "");

// mysql database name
define(DATABASE_NAME, "");

// mysql database table prefix
define(TABLE_PREFIX, "ae_");

/* Table Names */

// users table
define(TABLE_USERS, TABLE_PREFIX . "users");

// sessions table
define(TABLE_SESSIONS, TABLE_PREFIX . "sessions");

/* Advanced Settings */
// users table
define(USER_CONTENT_TYPE, "text/html;charset=UTF-8");

?>
Heres are my updated source code:
forgotpassword.php

Code: Select all

<?php

// disable display or error messages and log them instead
ini_set('error_reporting', E_ALL | E_STRICT);
ini_set('display_errors', 'On');
ini_set('log_errors', 'Off');
ini_set('error_log', '/logs/error_log');

// include smarty library
require('libs/Smarty.class.php');

// include configuration info
require_once('config.php');

// include database library
require_once('libs/Database.class.php');

// include user library
require_once('libs/User.class.php');

// create instance of smarty library
$smarty = new Smarty();

// set content header
header("Content-Type: " . USER_CONTENT_TYPE);

// if the form wasn't submited
if(!isset($_POST["submit"]))
{
	// display it
	$smarty->display('forgotpassword.tpl');
}
// otherwise the form was submitted
else
{
	// if the username is empty
	if(empty($_POST["username"]))
	{
		// so display an error stating the username is empty
		$smarty->assign('error', 'username is empty');

		// and display it
		$smarty->display('error.tpl');

		// and terminate
		exit;
	}
	// if the username is too short or too big
	elseif(strlen($_POST["username"]) < 4 || strlen($_POST["username"]) > 16)
	{
		// so display an error stating the username is empty
		$smarty->assign('error', 'username must be 4-16 characters long');

		// and display it
		$smarty->display('error.tpl');

		// and terminate
		exit;
	}
	// otherwise the username is filled in
	else
	{
		// so sanitize it
		$username = $_POST["username"];
	}

	// if the email is empty
	if(empty($_POST["email"]))
	{
		// so display an error stating the password is empty
		$smarty->assign('error', 'email is empty');

		// and display it
		$smarty->display('error.tpl');

		// and terminate
		exit;
	}
	// if the email is invalid
	elseif(!preg_match('/^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,3})$/', $_POST["email"]))
	{
		// so display an error stating the email is invalid
		$smarty->assign('error', 'the email address you entered is invalid');

		// and display it
		$smarty->display('error.tpl');

		// and terminate
		exit;
	}
	// otherwise the email is ok
	else
	{
		// so sanitize it
		$email = $_POST["email"];
	}

	// create instance of database class
	$database = new Database();

	// create instance of user class
	$user = new User($database);

	// check the users login info
	if(!$user->resetPassword($username, $email))
	{
		// otherwise display an error stating the the feature isn't implemented
		$smarty->assign('error', 'there was a problem contacting the database, please notify an admin');

		// display it
		$smarty->display('error.tpl');
		
	}
    else
    {
		// otherwise display an error stating the the feature isn't implemented
		$smarty->assign('error', 'if you provided correct info your password has been reset and an email has been sent with your new password');

		// display it
		$smarty->display('error.tpl');
	}
}

?>
User.class.php

Code: Select all

	/**
	* changes the users password 
	* @param $username username to check
	* @param $email user email tied to user
	* @return true if login is successful otherwise false
	*/
	public function resetPassword($username, $email)
	{
		// prepare the sql statement
		$statement = $this->db->prepare('SELECT salt FROM ' . TABLE_USERS . ' WHERE USERNAME = ? AND EMAIL = ? LIMIT 1');

		// bing the variables
		$statement->bind_param('ss', $username, $email);

		// if the statement executed successfully
		if ($statement->execute())
		{
			// get the number of results
			$statement->bind_result($resultsalt);

			// fetch the results
			$statement->fetch();
echo $resultsalt . "<br />";
			// if a result exists
			if($resultsalt)
			{
				// generate a new password
				$password = $this->generateRandomPassword(10);
echo $password . "<br />";
                // hash the password using the stored hash
                $passwordhash = $this->generateHash($password, $resultsalt);
echo $passwordhash . "<br />";
				// prepare the sql statement to change the password
				$statement = $this->db->prepare('UPDATE ' . TABLE_USERS . ' SET PASSWORD = ? WHERE USERNAME = ? AND EMAIL = ? LIMIT 1');

				// bing the variables
				$statement->bind_param('sss', $passwordhash, $username, $email);

				// if the statement executed successfully
				if ($statement->execute())
				{
					// get the number of results
					$statement->bind_result($result);
echo "Result<br>";
					// fetch the results
					$statement->fetch();

					// if a result exists
					if($result)
					{
						echo "Success!" . $password . "<br />";
					}

                    // return success
					return true;
        		}
				else
				{
					// second sql statement didn't execute so return false
					return false;
				}
			}
			else
			{
				// the query was successful but the info was incorrect so return true
				return true;
			}
		}
		else
		{
			// first sql statement didn't execute so return false
			return false;
		}
	}
And finally Database.class.php

Code: Select all

<?php

// import configuration data
require_once('./config.php');

class Database extends mysqli
{
	// instance of class
	private $instance;

	// class constructor
	public function __construct()
	{
		// turn on error reporting
        mysqli_report(MYSQLI_REPORT_OFF);

		parent::__construct(DATABASE_SERVER, DATABASE_USERNAME, DATABASE_PASSWORD, DATABASE_NAME);

		// if the connection couldn't be established
		if(mysqli_connect_errno())
		{
			// throw an exception
			throw new exception(mysqli_connect_error(), mysqli_connect_errno()); 
		}
	}
}

?>
Any assistance in this matter would be greatly appreciated.

Sincerely,

AleeiousMMO

Re: Not Working When Correct Info is provided

Posted: Mon Dec 23, 2013 8:20 am
by MikuzA
try

Code: Select all

define("DATABASE_SERVER", "localhost"); 

Re: Not Working When Correct Info is provided

Posted: Mon Dec 30, 2013 8:26 pm
by Aleeious
MikuzA wrote:try

Code: Select all

define("DATABASE_SERVER", "localhost");
Thanks that fixed one problem, now its crashing on this line:

Code: Select all

// prepare the sql statement to change the password
$statement = $this->db->prepare('UPDATE ' . TABLE_USERS . ' SET PASSWORD = ? WHERE USERNAME = ? AND EMAIL = ? LIMIT 1');
With the error:
Fatal error: Call to a member function bind_param() on a non-object in /home/aleeious/public_html/beta/libs/User.class.php on line 298
Everything else stays the same. Any assistance in this matter would be greatly appreciated.

Sincerely,

AleeiousMMO

Re: Not Working When Correct Info is provided

Posted: Thu Jan 02, 2014 11:51 am
by MikuzA
Have you checked that TABLE_USERS defined variable gives the expected result in that function?
Or try creating your query as a string and execute it manually.

Since I think the $statement is now FALSE due the query failing.

Re: Not Working When Correct Info is provided

Posted: Fri Jan 03, 2014 4:00 pm
by Aleeious
I got it to update the password but, it's giving me this warning:
Warning: mysqli_stmt::fetch() [mysqli-stmt.fetch]: (HY000/2053): Attempt to read a row while there is no result set associated with the statement in /home/aleeious/public_html/beta/libs/User.class.php on line 309
which corrisponds to this line:

Code: Select all

$statement->fetch();
Here is the updated code:

Code: Select all

/**
	* changes the users password 
	* @param $username username to check
	* @param $email user email tied to user
	* @return true if login is successful otherwise false
	*/
	public function resetPassword($username, $email)
	{
		// prepare the sql statement
		$statement = $this->db->prepare('SELECT salt FROM ' . TABLE_USERS . ' WHERE username = ? AND email = ? LIMIT 1');

		// bing the variables
		$statement->bind_param('ss', $username, $email);

		// if the statement executed successfully
		if ($statement->execute())
		{
			// get the number of results
			$statement->bind_result($resultsalt);

			// fetch the results
			$statement->fetch();
echo $resultsalt . "<br />";
			// if a result exists
			if($resultsalt)
			{
				// generate a new password
				$password = $this->generateRandomPassword(10);
echo $password . "<br />";
                // hash the password using the stored hash
                $passwordhash = $this->generateHash($password, $resultsalt);
echo $passwordhash . "<br />";
echo "TABLE_USERS: " . TABLE_USERS;

				// free up the last query
				$statement->close();

				// prepare the sql statement to change the password
				$statement = $this->db->prepare("UPDATE " . TABLE_USERS . " SET `password` = ? WHERE username = ? AND email = ? LIMIT 1");

				// bing the variables
				$statement->bind_param('sss', $passwordhash, $username, $email);

				// if the statement executed successfully
				if ($statement->execute())
				{
					// fetch the results
					$statement->fetch();

					// email the user the new password
					mail($email, "Your New Password", "Someone possibly you has asked to have your password reset. Your new password is: " . $password . ". If you did not ask to have your password reset, please contact the admin.");

                    // return success
					return true;
        		}
				else
				{
					// second sql statement didn't execute so return false
					return false;
				}
			}
			else
			{
				// the query was successful but the info was incorrect so return true
				return true;
			}
		}
		else
		{
			// first sql statement didn't execute so return false
			return false;
		}
	}
Any assistance in this matter would be greatly appreciated.

Sincerely,

Aleeious MMO

Re: Not Working When Correct Info is provided

Posted: Sun Jan 05, 2014 5:56 am
by MikuzA
I'm not 100% sure when it comes to mysqli but as general PHP knowledge this fetch looks like it should be removed due its not returning anything when update is happening>

Code: Select all

           // prepare the sql statement to change the password
            $statement = $this->db->prepare("UPDATE " . TABLE_USERS . " SET `password` = ? WHERE username = ? AND email = ? LIMIT 1");

            // bing the variables
            $statement->bind_param('sss', $passwordhash, $username, $email);

            // if the statement executed successfully
            if ($statement->execute())
            {
               // fetch the results
               $statement->fetch(); <--------- remove
Or is it the first $statement->fetch(); where it gives the Warning?