<commit_before><?php

	include('Encrypt.class.php');
    include('PHP_mailer.class.php');
	include('Configuration.php');
    class Authenticate 
	{
	    //The database settings and table structures are inherited from the Configuration.php file.
		private $db_host = DB_HOST;
        private $db_username = DB_USERNAME;
        private $db_password = <PASSWORD>;
        private $db_name = DEFAULT_DB;
        private $user_table = TABLE_WITH_USERS;
		private $email_col = COLUMN_WITH_EMAILS;
		private $password_col = COLUMN_WITH_PASSWORD_HASHES;
        private $activated_col = COLUMN_CONFIRMING_ACCOUNT_ACTIVATION;
        private $emailed_hash_col = COLUMN_WITH_EMAILED_HASHES;
		
        private $mysqli;
        
	 	function __construct()
		{
			$this->mysqli = new mysqli($db_host, $db_username, $db_password, $db_name);			
        }
		
		function create_user($email, $password, $confirm_password)
		{
            if($password == $confirm_password)
            {
                //Generate password.
                $encrypt = new Encrypt(12, FALSE);
                $password = $encrypt->hash_password($password);
                    
                //Add user to database.
                $stmt = $this->mysqli->prepare("INSERT INTO `$this->user_table`(`$this->email_col`, `$this->password_col`) VALUES(?, ?)");   
                $stmt->bind_param('ss', $email, $password);
                $stmt->execute();
                  
                if(!$this->mysqli->error)
                {
                    return validate_email($email);    
                }
            }                                
        }
        
        function login($email, $password) 
        {
            //Fetch password and emailed_hash from database, to check if the account has been activated.
            $stmt = $this->mysqli->prepare("SELECT `$this->password_col`, `$this->emailed_hash_col` FROM `$this->user_table` WHERE `$this->email_col` = ?");
            $stmt->bind_param('s', $email);
            $stmt->execute();
            $stmt->bind_result($password_hash, $emailed_hash);
            $stmt->fetch();
              
            if(!$this->mysqli->error)
            {  
                //Check if the account has been verified.
                if(strpos($emailed_hash, 'unverified') !== FALSE)
                {
                    return 2;
                }
                                                
                //Check if the password hashes match
                $encrypt = new Encrypt(12, FALSE);            
                return $encrypt->check_password($password, $password_hash);      
            }    
        }   
        
        //Change user password.
        function change_password($email, $password, $new_password, $confirm_new_password)
        {
            if($new_password == $confirm_new_password)
            {
                if(login($email, $password))
                {
                    return set_password($email, $new_password);
                }
            }
        }       
        
        //Email a password reset link embedded with a unique hash.
        function reset_password($email)
        {
            $random_hash = generate_random_hash();
            
            //The 'reset' flag will be checked when the password reset link is clicked, to make sure the user did actually request a password reset.
            $random_hash = 'reset'.$random_hash;
            
            $stmt = $this->mysqli->prepare("UPDATE `$this->user_table` SET `$this->emailed_hash_col` = ? WHERE `$this->email_col` = ?");
            $stmt->bind_param('ss', $random_hash, $email);
            $stmt->execute();    

            if(!$this->mysqli->error)
            {
                $mail = generate_email($email, 'reset', $random_hash);
                
                if($mail->Send())
                {
                    return TRUE;
                }                   
            }
        }
        
        //When the GET variable is found in the URL, a user has either clicked a password reset link, OR an email validation link. This function will check the hash and return the type. 
        function check_hash($hash)
        {
            $stmt = $this->mysqli->prepare("SELECT `$this->emailed_hash_col` FROM `$this->user_table` WHERE `$this->emailed_hash_col` = ?");
            $stmt->bind_param('s', $hash);
            $stmt->execute();
            $stmt->bind_result($result);
            $stmt->fetch();
            
            if($hash === $result)
            {
                if(strpos($hash, 'reset') !== FALSE)
                {
                    return 'reset';
                }
                elseif(strpos($hash, 'unverified') !== FALSE)
                {
                    return 'unverified';
                }  
            }                 
        }
        
        function logout() 
        {
            session_start();
            $_SESSION = array();
            return session_destroy();  
        }
        
        function set_password($email, $password)
        {
            //Encrypt password.
            $encrypt = new Encrypt(12, FALSE);
            $password = $encrypt->hash_password($password);
            
            //Insert password.
            $stmt = $this->mysqli->prepare("UPDATE `$this->user_table` SET `$this->password_col` = ? WHERE `$this->email_col` = ?");
            $stmt->bind_param('ss', $password, $email);
            $stmt->execute();
                
            return empty($this->mysqli->error);
        }       
        
        //Send a link with an embedded unique hash as an email. Called by create_user().
        private function validate_email($email)
        {
            $random_hash = generate_random_hash();      
            $random_hash = 'unverified'.$random_hash;
            
            //Insert the hash into the database.
            $stmt = $this->mysqli->prepare("INSERT INTO `$this->user_table`(`$this->emailed_hash_col`) VALUES(?) WHERE `$this->email_col` = ?");
            $stmt->bind_param('ss', $random_hash, $email);
            $stmt->execute();
            
            if(!$this->mysqli->error)
            {
                $mail = generate_email($email, 'registration', $random_hash);
                
                if($mail->Send())
                {
                    return TRUE;
                }
            }        
        }
		
        //Mark the account as activated when check_hash() returns 'unverified.'
        function account_activated($hash)
        {
            //Mark the account as activated by removing the 'unverified' flag.
            $new_hash = str_replace('unverified', '', $hash);
                
            //Update the 'Activated' field to TRUE, and set the modified $hash.
            $stmt = $this->mysqli->prepare("UPDATE `$this->user_table` SET `$this->activated_col` = 'TRUE', `$this->emailed_hash_col` = ? WHERE `$this->emailed_hash_col` = ?");
            $stmt->bind_param('ss', $new_hash, $hash);
            $stmt->execute();
              
            return empty($this->mysqli->error);
        }
        
        //Generate a unique 32 character long hash. Called by create_user(), reset_password() and validate_email().
        private function generate_random_hash()
        {
            //Check if the $random_hash has been used before, and if yes, then generate another one until a unique hash is found.
            $stmt = $this->mysqli->prepare("SELECT `$this->emailed_hash_col` FROM `$this->user_table` WHERE `$this->emailed_hash_col` = ? LIMIT 1");
            do
            {
                $random_hash = md5(uniqid(rand(), true));    
                $stmt->bind_param('s', $random_hash);
                $stmt->execute();
                $stmt->bind_result($emailed_hash_col);
                $stmt->fetch();
            }
            while($emailed_hash_col == $random_hash);   
            <commit_msg>Alter comments in Authenticate file.<commit_after><?php

	include('Encrypt.class.php');
    include('PHP_mailer.class.php');
	include('Configuration.php');
    class Authenticate 
	{
	    //The database settings and table structures are inherited from the Configuration.php file.
		private $db_host = DB_HOST;
        private $db_username = DB_USERNAME;
        private $db_password = <PASSWORD>;
        private $db_name = DEFAULT_DB;
        private $user_table = TABLE_WITH_USERS;
		private $email_col = COLUMN_WITH_EMAILS;
		private $password_col = COLUMN_WITH_PASSWORD_HASHES;
        private $activated_col = COLUMN_CONFIRMING_ACCOUNT_ACTIVATION;
        private $emailed_hash_col = COLUMN_WITH_EMAILED_HASHES;
		
        private $mysqli;
        
	 	function __construct()
		{
			$this->mysqli = new mysqli($db_host, $db_username, $db_password, $db_name);			
        }
		
		function create_user($email, $password, $confirm_password)
		{
            if($password == $confirm_password)
            {
                //Generate password.
                $encrypt = new Encrypt(12, FALSE);
                $password = $encrypt->hash_password($password);
                    
                //Add user to database.
                $stmt = $this->mysqli->prepare("INSERT INTO `$this->user_table`(`$this->email_col`, `$this->password_col`) VALUES(?, ?)");   
                $stmt->bind_param('ss', $email, $password);
                $stmt->execute();
                  
                if(!$this->mysqli->error)
                {
                    return validate_email($email);    
                }
            }                                
        }
        
        function login($email, $password) 
        {
            //Fetch password and emailed_hash from database, to check if the account has been activated.
            $stmt = $this->mysqli->prepare("SELECT `$this->password_col`, `$this->emailed_hash_col` FROM `$this->user_table` WHERE `$this->email_col` = ?");
            $stmt->bind_param('s', $email);
            $stmt->execute();
            $stmt->bind_result($password_hash, $emailed_hash);
            $stmt->fetch();
              
            if(!$this->mysqli->error)
            {  
                //Check if the account has been verified.
                if(strpos($emailed_hash, 'unverified') !== FALSE)
                {
                    return 2;
                }
                                                
                //Check if the password hashes match
                $encrypt = new Encrypt(12, FALSE);            
                return $encrypt->check_password($password, $password_hash);      
            }    
        }   
        
        //Change user password.
        function change_password($email, $password, $new_password, $confirm_new_password)
        {
            if($new_password == $confirm_new_password)
            {
                if(login($email, $password))
                {
                    return set_password($email, $new_password);
                }
            }
        }       
        
        //Email a password reset link embedded with a unique hash.
        function reset_password($email)
        {
            $random_hash = generate_random_hash();
            
            //The 'reset' flag will be checked when the password reset link is clicked, to make sure the user did actually request a password reset.
            $random_hash = 'reset'.$random_hash;
            
            $stmt = $this->mysqli->prepare("UPDATE `$this->user_table` SET `$this->emailed_hash_col` = ? WHERE `$this->email_col` = ?");
            $stmt->bind_param('ss', $random_hash, $email);
            $stmt->execute();    

            if(!$this->mysqli->error)
            {
                $mail = generate_email($email, 'reset', $random_hash);
                
                if($mail->Send())
                {
                    return TRUE;
                }                   
            }
        }
        
        //When the GET variable is found in the URL, a user has either clicked a password reset link, OR an email validation link. This function will check the hash and return the type. 
        function check_hash($hash)
        {
            $stmt = $this->mysqli->prepare("SELECT `$this->emailed_hash_col` FROM `$this->user_table` WHERE `$this->emailed_hash_col` = ?");
            $stmt->bind_param('s', $hash);
            $stmt->execute();
            $stmt->bind_result($result);
            $stmt->fetch();
            
            if($hash === $result)
            {
                if(strpos($hash, 'reset') !== FALSE)
                {
                    return 'reset';
                }
                elseif(strpos($hash, 'unverified') !== FALSE)
                {
                    return 'unverified';
                }  
            }                 
        }
        
        function logout() 
        {
            session_start();
            $_SESSION = array();
            return session_destroy();  
        }
        
        function set_password($email, $password)
        {
            //Encrypt the password.
            $encrypt = new Encrypt(12, FALSE);
            $password = $encrypt->hash_password($password);
            
            //Insert the password, and delete the emailed_hash column just in case this function was called after a password reset.
            $stmt = $this->mysqli->prepare("UPDATE `$this->user_table` SET `$this->password_col` = ?, `$this->emailed_hash_col` = '' WHERE `$this->email_col` = ?");
            $stmt->bind_param('ss', $password, $email);
            $stmt->execute();
                
            return empty($this->mysqli->error);
        }       
        
        //Send a link with an embedded unique hash as an email. Called by create_user().
        private function validate_email($email)
        {
            $random_hash = generate_random_hash();      
            $random_hash = 'unverified'.$random_hash;
            
            //Insert the hash into the database.
            $stmt = $this->mysqli->prepare("INSERT INTO `$this->user_table`(`$this->emailed_hash_col`) VALUES(?) WHERE `$this->email_col` = ?");
            $stmt->bind_param('ss', $random_hash, $email);
            $stmt->execute();
            
            if(!$this->mysqli->error)
            {
                $mail = generate_email($email, 'registration', $random_hash);
                
                if($mail->Send())
                {
                    return TRUE;
                }
            }        
        }
		
        //Mark the account as activated.
        function account_activated($hash)
        {
            //Mark the account as activated by removing the 'unverified' flag.
            $new_hash = str_replace('unverified', '', $hash);
                
            //Update the 'Activated' field to TRUE, and set the modified $hash.
            $stmt = $this->mysqli->prepare("UPDATE `$this->user_table` SET `$this->activated_col` = 'TRUE', `$this->emailed_hash_col` = ? WHERE `$this->emailed_hash_col` = ?");
            $stmt->bind_param('ss', $new_hash, $hash);
            $stmt->execute();
              
            return empty($this->mysqli->error);
        }
        
        //Generate a unique 32 character long hash. Called by create_user(), reset_password() and validate_email().
        private function generate_random_hash()
        {
            //Check if the $random_hash has been used before, and if yes, then generate another one until a unique hash is found.
            $stmt = $this->mysqli->prepare("SELECT `$this->emailed_hash_col` FROM `$this->user_table` WHERE `$this->emailed_hash_col` = ? LIMIT 1");
            do
            {
                $random_hash = md5(uniqid(rand(), true));    
                $stmt->bind_param('s', $random_hash);
                $stmt->execute();
                $stmt->bind_result($emailed_hash_col);
                $stmt->fetch();
            }
            while($emailed_hash_col == $random_hash);   
            
{'fraction_non_alphanumeric': 0.12105887494537054, 'fraction_numerical': 0.0013735406130985827, 'mean_word_length': 1.5328905755850728, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 170, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 8, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1420985', 'n_tokens_mistral': 4376, 'n_tokens_neox': 4200, 'n_words': 943}