require_once 'handlers/db_hook.inc';
    $l = openDB();
    $r = mysqli_query($l, "SELECT password FROM `userdata` WHERE username='******'user']) . "'");
    $hba = mysqli_fetch_array($r);
    $hb = $hba[0];
    $a = json_decode($hb, true);
    print_r($a);
    require_once 'stronghash/php-stronghash.php';
    require_once 'handlers/login_functions.php';
    $h = new Stronghash();
    $u = new UserFunctions();
    // user validation
    echo "<pre> LookupUser results -- ";
    print_r($u->lookupUser($_POST['user'], $_POST['pw_base'], true));
    echo "\n VerifyHash results --";
    print_r($h->verifyHash($_POST['pw_base'], $a, null, null, null, true));
    echo "</pre>";
}
?>
    <article>
      <?php 
require_once 'login.php';
echo $login_output;
?>
      <div>
        <h3>Test Hash</h3>
        <p>You can check to ensure the proper functioning of the hashing here. Please note these passwords in the next field are plaintext.</p>
        <form action='?t=hash' method='post'>
          <input type='email' name='user' placeholder='username'/><br/>
          <input type='text' name='pw_base' placeholder='pass'/><br/>
          <input type='submit'/>
 public function lookupUser($username, $pw, $return = true, $totp_code = false, $override = false)
 {
     /***
      * Primary function to check login validation.
      *
      * @param string|int $username a username looking at a column set by the
      * usercol of this object
      * @param string $pw the plaintext password of the user
      * @param bool $return whether to return user data, or just the
      *                      boolean lookup state
      * @param bool|int $totp_code - false if none is needed/given,
      *                              otherwise the code
      * @param bool $override
      ***/
     if (strlen($pw) > 8192) {
         throw new Exception('Passwords must be less than 8192 characters in length.');
     }
     # check it's a valid email! validation skipped.
     $xml = new Xml();
     $result = $this->lookupItem($username, $this->userColumn);
     if ($result !== false) {
         try {
             $userdata = mysqli_fetch_assoc($result);
             if (is_numeric($userdata['id'])) {
                 # check password
                 if (!class_exists('Stronghash')) {
                     require_once dirname(__FILE__) . '/../core/stronghash/php-stronghash.php';
                 }
                 $hash = new Stronghash();
                 $data = json_decode($userdata[$this->pwColumn], true);
                 $original_data = $data;
                 $data['raw_db'] = $userdata[$this->pwColumn];
                 # Decrypt the password if totp_code is_numeric()
                 if (is_numeric($totp_code)) {
                     $pw = $this->decryptWithStoredKey($pw);
                 }
                 if (empty($data) || empty($data['salt'])) {
                     try {
                         # Try legacy
                         $xml->setXml($userdata['data']);
                         $data['algo'] = $xml->getTagContents('<algo>');
                         $data['rounds'] = $xml->getTagContents('<rounds>');
                         /* Default rounds for sha512 */
                         if (empty($data['rounds'])) {
                             $data['rounds'] = 10000;
                         }
                         if (empty($data['algo'])) {
                             $data['algo'] = 'sha512';
                         }
                         $data['salt'] = null;
                         $data['hash'] = $userdata['pass'];
                         $data['legacy'] = true;
                         $pw = $userdata['salt'] . $pw . $userdata['creation'];
                     } catch (Exception $e) {
                         return array(false, 'status' => false, 'message' => 'No valid password data');
                     }
                 }
                 if ($hash->verifyHash($pw, $data)) {
                     $this->getUser($userdata[$this->userColumn]);
                     ## Does the user have 2-factor authentication?
                     if ($this->has2FA()) {
                         $l = $this->openDB();
                         if (empty($totp_code)) {
                             # The user has 2FA turned on, prompt it
                             /*
                              * Here we create a temporary, dummy
                              * password for the client to save and
                              * pass again. Since we're storing an
                              * encrypted hash, even the data being
                              * taken is no more "public" than it
                              * already is in the password
                              * column. However, it keeps us validating
                              * a session in progress of TOTP-ing.
                              */
                             $key = Stronghash::createSalt();
                             $query = 'UPDATE `' . $this->getTable() . '` SET `' . $this->tmpColumn . "`='{$key}' WHERE `" . $this->userColumn . "`='" . $this->username . "'";
                             $r = mysqli_query($l, $query);
                             if ($r === false) {
                                 throw new Exception('Unable to encrypt password');
                             }
                             $encrypted_pw = urlencode(self::encryptThis($key, $pw, $this->getIV()));
                             # Encrypt the keys to validate the user asynchronously
                             # Of course, this this was called asynchronously, the keys will be empty ...
                             $cookiekey = $this->domain . '_secret';
                             #$cookiekey=str_replace(".","_",$this->domain)."_secret";
                             $cookieauth = $this->domain . '_auth';
                             #$cookieauth=str_replace(".","_",$this->domain)."_auth";
                             $encrypted_secret = self::encryptThis($key, $_COOKIE[$cookiekey], $this->getIV());
                             $encrypted_hash = self::encryptThis($key, $_COOKIE[$cookieauth], $this->getIV());
                             return array(false, 'status' => false, 'totp' => true, 'error' => false, 'human_error' => 'Please enter the code generated by the authenticator application on your device.', 'encrypted_password' => $encrypted_pw, 'encrypted_secret' => $encrypted_secret, 'encrypted_hash' => $encrypted_hash);
                         }
                         if ($this->verifyTOTP($totp_code) !== true) {
                             # Bad TOTP code
                             return array(false, 'status' => false, 'totp' => true, 'error' => 'Invalid TOTP code', 'human_error' => 'Bad verification code. Please try again.');
                         }
                         # Remove the encryption key
                         $query = 'UPDATE `' . $this->getTable() . '` SET `' . $this->tmpColumn . "`='' WHERE `" . $this->userColumn . "`='" . $this->username . "'";
                         mysqli_query($l, $query);
                         # Return decrypted userdata, if applicable
                         # The salt is the password key "salt"
                         $decname = self::decryptThis($data['salt'] . $pw, $userdata['name'], $this->getIV());
                         if (empty($decname)) {
                             $decname = $userdata['name'];
                         }
                         if (!$return) {
                             return array(true, $decname, 'status' => true);
                         } else {
                             $returning = array(true, $userdata, 'status' => true, 'data' => $userdata);
                             return $returning;
                         }
                     }
                     if (($userdata['flag'] || $override) && !$userdata['disabled']) {
                         # This user is OK and not disabled, nor pending validation
                         # Return decrypted userdata, if applicable
                         # The salt is the password key "salt"
                         $decname = self::decryptThis($data['salt'] . $pw, $userdata['name'], $this->getIV());
                         if (empty($decname)) {
                             $decname = $userdata['name'];
                         }
                         if (!$return) {
                             return array(true, $decname, 'status' => true);
                         } else {
                             $returning = array(true, $userdata, 'status' => true, 'data' => $userdata);
                             return $returning;
                         }
                     } else {
                         if (!$userdata['flag']) {
                             return array(false, 'status' => false, 'message' => 'Your login information is correct, but your account is still being validated, or has been disabled. Please try again later.');
                         }
                         if ($userdata['disabled']) {
                             # do a time check
                             if ($userdata['dtime'] + 3600 > self::microtime_float()) {
                                 $rem = intval($userdata['dtime']) - intval(self::microtime_float()) + 3600;
                                 $min = $rem % 60;
                                 $sec = $rem - 60 * $min;
                                 return array(false, 'status' => false, 'message' => 'Your account has been disabled for too many failed login attempts. Please try again in ' . $min . ' minutes and ' . $sec . ' seconds.');
                             } else {
                                 # Clear login disabled flag
                                 $query1 = 'UPDATE `' . $this->getTable() . '` SET `disabled`=false WHERE `id`=' . $userdata['id'];
                                 $l = $this->openDB();
                                 $result = mysqli_query($l, $query1);
                             }
                         }
                         # All checks passed.
                         if (!$return) {
                             $decname = self::decryptThis($salt . $pw, $userdata['name'], $this->getIV());
                             if (empty($decname)) {
                                 $decname = $userdata['name'];
                             }
                             return array(true, $decname, 'status' => true);
                         } else {
                             $userdata['img'] = $this->getUserPicture();
                             $returning = array(true, $userdata, 'status' => true, 'data' => $userdata);
                             return $returning;
                         }
                     }
                 } else {
                     return array(false, 'status' => false, 'message' => 'Sorry, your username or password is incorrect.', 'error' => 'Bad Password');
                     # , "data" => $data, "check_results" => $hash->verifyHash($pw, $data, null, null, null, true)
                 }
                 # end good username loop
             } else {
                 return array(false, 'status' => false, 'message' => 'Sorry, your username or password is incorrect.', 'error' => 'Bad username', 'desc' => 'No numeric id');
             }
         } catch (Exception $e) {
             return array(false, 'status' => false, 'message' => 'System error. Please try again. If the problem persists, please report it.', 'error' => $e->getMessage());
         }
     } else {
         return array(false, 'status' => false, 'message' => 'Sorry, your username or password is incorrect.', 'error' => 'Bad username', 'desc' => $result['error']);
     }
 }