├── README ├── auth.class.php ├── auth.sql ├── config.php └── lang.php /README: -------------------------------------------------------------------------------- 1 | User Authentication PHP Class 2 | ============================= 3 | 4 | This is a simple user authentication class for PHP, which uses 5 | a MySQL Database which is accessed via MySQLi. 6 | 7 | The system also includes a Custom user session system, meaning 8 | sessions can last a predefined time, for example, 1 minute to over 10 years 9 | if that was ever needed. 10 | 11 | The Current functions are as follows : 12 | 13 | - login($username, $password) : Verifies user credentials 14 | - register($username, $password, $verifypassword, $email) : Adds a new user account to the database 15 | - newsession($username) : Creates a new session for the user 16 | - deletesession($hash) : Deletes an existing session from the database, and removes the user's cookie 17 | - sessioninfo($hash) : Retrieves info about the session from database (UID, Username, Expire Date, IP) 18 | - checksession($hash) : Checks if session is valid 19 | - randomkey($length) : Returns a random key, used as activation key, contain lowercase / uppercase letters and numbers 20 | - activate($username, $key) : Activates an account based on username and activation key 21 | - changepass($username, $currpass, $newpass, $verifynewpass) : Changes the user's password. Requires current password 22 | - changeemail($username, $email) : Changes the user's email 23 | - resetpass($username, $email, $key, $newpass, $verifynewpass) : Sends reset request email and resets user's password 24 | - checkresetkey($username, $key) : Checks the reset key based on username, returns true / false 25 | - deleteaccount($username, $password) : Deletes the user's account. Requires current password 26 | - addattempt($ip) : Logs a new attempt of authentication based on user IP 27 | - getattempt($ip) : Retrieves amount of attempts from database based on user IP 28 | - expireattempt() : Removes expired attempt logs from database, should be ran as cron job 29 | - LogActivity($username, $action, $additionalinfo) : Logs the user's usage of the class, from login to logout. Includes attempts. 30 | - hashpassword($password) : Hashes the password with the following : hash("SHA512", base64_encode(str_rot13(hash("SHA512", str_rot13($auth_conf['salt_1'] . $password . $auth_conf['salt_2']))))) 31 | 32 | The extended encryption will result in a pratically uncrackable password. The session 33 | system relies on the user's IP, if it changes, the user will have to reauthenticate. 34 | 35 | Database layout is stored in auth.sql which you can import easily with PhpMyAdmin 36 | 37 | Auth configuration is done in config.php where you can configure the MySQL database settings, attempts settings, email settings etc... 38 | -------------------------------------------------------------------------------- /auth.class.php: -------------------------------------------------------------------------------- 1 | mysqli = new mysqli($db['host'], $db['user'], $db['pass'], $db['name']); 14 | unset($db['pass']); // $mysqli is public, remove password for security 15 | } 16 | 17 | /* 18 | * Log user in via MySQL Database 19 | * @param string $username 20 | * @param string $password 21 | * @return boolean 22 | */ 23 | 24 | function login($username, $password) 25 | { 26 | include("config.php"); 27 | include("lang.php"); 28 | 29 | if(!isset($_COOKIE["auth_session"])) 30 | { 31 | $attcount = $this->getattempt($_SERVER['REMOTE_ADDR']); 32 | 33 | if($attcount >= $auth_conf['max_attempts']) 34 | { 35 | $this->errormsg[] = $lang[$loc]['auth']['login_lockedout']; 36 | $this->errormsg[] = $lang[$loc]['auth']['login_wait30']; 37 | 38 | return false; 39 | } 40 | else 41 | { 42 | // Input verification : 43 | 44 | if(strlen($username) == 0) { $this->errormsg[] = $lang[$loc]['auth']['login_username_empty']; return false; } 45 | elseif(strlen($username) > 30) { $this->errormsg[] = $lang[$loc]['auth']['login_username_long']; return false; } 46 | elseif(strlen($username) < 3) { $this->errormsg[] = $lang[$loc]['auth']['login_username_short']; return false; } 47 | elseif(strlen($password) == 0) { $this->errormsg[] = $lang[$loc]['auth']['login_password_empty']; return false; } 48 | elseif(strlen($password) > 30) { $this->errormsg[] = $lang[$loc]['auth']['login_password_short']; return false; } 49 | elseif(strlen($password) < 5) { $this->errormsg[] = $lang[$loc]['auth']['login_password_long']; return false; } 50 | else 51 | { 52 | // Input is valid 53 | 54 | $password = $this->hashpass($password); 55 | 56 | $query = $this->mysqli->prepare("SELECT isactive FROM users WHERE username = ? AND password = ?"); 57 | $query->bind_param("ss", $username, $password); 58 | $query->bind_result($isactive); 59 | $query->execute(); 60 | $query->store_result(); 61 | $count = $query->num_rows; 62 | $query->fetch(); 63 | $query->close(); 64 | 65 | if($count == 0) 66 | { 67 | // Username and / or password are incorrect 68 | 69 | $this->errormsg[] = $lang[$loc]['auth']['login_incorrect']; 70 | 71 | $this->addattempt($_SERVER['REMOTE_ADDR']); 72 | 73 | $attcount = $attcount + 1; 74 | $remaincount = $auth_conf['max_attempts'] - $attcount; 75 | 76 | $this->LogActivity("UNKNOWN", "AUTH_LOGIN_FAIL", "Username / Password incorrect - {$username} / {$password}"); 77 | 78 | $this->errormsg[] = sprintf($lang[$loc]['auth']['login_attempts_remaining'], $remaincount); 79 | 80 | return false; 81 | } 82 | else 83 | { 84 | // Username and password are correct 85 | 86 | if($isactive == "0") 87 | { 88 | // Account is not activated 89 | 90 | $this->LogActivity($username, "AUTH_LOGIN_FAIL", "Account inactive"); 91 | 92 | $this->errormsg[] = $lang[$loc]['auth']['login_account_inactive']; 93 | 94 | return false; 95 | } 96 | else 97 | { 98 | // Account is activated 99 | 100 | $this->newsession($username); 101 | 102 | $this->LogActivity($username, "AUTH_LOGIN_SUCCESS", "User logged in"); 103 | 104 | $this->successmsg[] = $lang[$loc]['auth']['login_success']; 105 | 106 | return true; 107 | } 108 | } 109 | } 110 | } 111 | } 112 | else 113 | { 114 | // User is already logged in 115 | 116 | $this->errormsg[] = $lang[$loc]['auth']['login_already']; 117 | 118 | return false; 119 | } 120 | } 121 | 122 | /* 123 | * Register a new user into the database 124 | * @param string $username 125 | * @param string $password 126 | * @param string $verifypassword 127 | * @param string $email 128 | * @return boolean 129 | */ 130 | 131 | function register($username, $password, $verifypassword, $email) 132 | { 133 | include("config.php"); 134 | include("lang.php"); 135 | 136 | if(!isset($_COOKIE["auth_session"])) 137 | { 138 | 139 | // Input Verification : 140 | 141 | if(strlen($username) == 0) { $this->errormsg[] = $lang[$loc]['auth']['register_username_empty']; } 142 | elseif(strlen($username) > 30) { $this->errormsg[] = $lang[$loc]['auth']['register_username_long']; } 143 | elseif(strlen($username) < 3) { $this->errormsg[] = $lang[$loc]['auth']['register_username_short']; } 144 | if(strlen($password) == 0) { $this->errormsg[] = $lang[$loc]['auth']['register_password_empty']; } 145 | elseif(strlen($password) > 30) { $this->errormsg[] = $lang[$loc]['auth']['register_password_long']; } 146 | elseif(strlen($password) < 5) { $this->errormsg[] = $lang[$loc]['auth']['register_password_short']; } 147 | elseif($password !== $verifypassword) { $this->errormsg[] = $lang[$loc]['auth']['register_password_nomatch']; } 148 | elseif(strstr($password, $username)) { $this->errormsg[] = $lang[$loc]['auth']['register_password_username']; } 149 | if(strlen($email) == 0) { $this->errormsg[] = $lang[$loc]['auth']['register_email_empty']; } 150 | elseif(strlen($email) > 100) { $this->errormsg[] = $lang[$loc]['auth']['register_email_long']; } 151 | elseif(strlen($email) < 5) { $this->errormsg[] = $lang[$loc]['auth']['register_email_short']; } 152 | elseif(!filter_var($email, FILTER_VALIDATE_EMAIL)) { $this->errormsg[] = $lang[$loc]['auth']['register_email_invalid']; } 153 | 154 | if(count($this->errormsg) == 0) 155 | { 156 | // Input is valid 157 | 158 | $query = $this->mysqli->prepare("SELECT * FROM users WHERE username=?"); 159 | $query->bind_param("s", $username); 160 | $query->execute(); 161 | $query->store_result(); 162 | $count = $query->num_rows; 163 | $query->close(); 164 | 165 | if($count != 0) 166 | { 167 | // Username already exists 168 | 169 | $this->LogActivity("UNKNOWN", "AUTH_REGISTER_FAIL", "Username ({$username}) already exists"); 170 | 171 | $this->errormsg[] = $lang[$loc]['auth']['register_username_exist']; 172 | 173 | return false; 174 | } 175 | else 176 | { 177 | // Username is not taken 178 | 179 | $query = $this->mysqli->prepare("SELECT * FROM users WHERE email=?"); 180 | $query->bind_param("s", $email); 181 | $query->execute(); 182 | $query->store_result(); 183 | $count = $query->num_rows; 184 | $query->close(); 185 | 186 | if($count != 0) 187 | { 188 | // Email address is already used 189 | 190 | $this->LogActivity("UNKNOWN", "AUTH_REGISTER_FAIL", "Email ({$email}) already exists"); 191 | 192 | $this->errormsg[] = $lang[$loc]['auth']['register_email_exist']; 193 | 194 | return false; 195 | } 196 | else 197 | { 198 | // Email address isn't already used 199 | 200 | $password = $this->hashpass($password); 201 | $activekey = $this->randomkey(15); 202 | 203 | $query = $this->mysqli->prepare("INSERT INTO users (username, password, email, activekey) VALUES (?, ?, ?, ?)"); 204 | $query->bind_param("ssss", $username, $password, $email, $activekey); 205 | $query->execute(); 206 | $query->close(); 207 | 208 | $message_from = $auth_conf['email_from']; 209 | $message_subj = $auth_conf['site_name'] . " - Account activation required !"; 210 | $message_cont = "Hello {$username}

"; 211 | $message_cont .= "You recently registered a new account on " . $auth_conf['site_name'] . "
"; 212 | $message_cont .= "To activate your account please click the following link

"; 213 | $message_cont .= "Activate my account"; 214 | $message_head = "From: {$message_from}" . "\r\n"; 215 | $message_head .= "MIME-Version: 1.0" . "\r\n"; 216 | $message_head .= "Content-type: text/html; charset=iso-8859-1" . "\r\n"; 217 | 218 | mail($email, $message_subj, $message_cont, $message_head); 219 | 220 | $this->LogActivity($username, "AUTH_REGISTER_SUCCESS", "Account created and activation email sent"); 221 | 222 | $this->successmsg[] = $lang[$loc]['auth']['register_success']; 223 | 224 | return true; 225 | } 226 | } 227 | } 228 | else 229 | { 230 | return false; 231 | } 232 | } 233 | else 234 | { 235 | // User is logged in 236 | 237 | $this->errormsg[] = $lang[$loc]['auth']['register_email_loggedin']; 238 | 239 | return false; 240 | } 241 | } 242 | 243 | /* 244 | * Creates a new session for the provided username and sets cookie 245 | * @param string $username 246 | */ 247 | 248 | function newsession($username) 249 | { 250 | include("config.php"); 251 | 252 | $hash = md5(microtime()); 253 | 254 | // Fetch User ID : 255 | 256 | $query = $this->mysqli->prepare("SELECT id FROM users WHERE username=?"); 257 | $query->bind_param("s", $username); 258 | $query->bind_result($uid); 259 | $query->execute(); 260 | $query->fetch(); 261 | $query->close(); 262 | 263 | // Delete all previous sessions : 264 | 265 | $query = $this->mysqli->prepare("DELETE FROM sessions WHERE username=?"); 266 | $query->bind_param("s", $username); 267 | $query->execute(); 268 | $query->close(); 269 | 270 | $ip = $_SERVER['REMOTE_ADDR']; 271 | $expiredate = date("Y-m-d H:i:s", strtotime($auth_conf['session_duration'])); 272 | $expiretime = strtotime($expiredate); 273 | 274 | $query = $this->mysqli->prepare("INSERT INTO sessions (uid, username, hash, expiredate, ip) VALUES (?, ?, ?, ?, ?)"); 275 | $query->bind_param("issss", $uid, $username, $hash, $expiredate, $ip); 276 | $query->execute(); 277 | $query->close(); 278 | 279 | setcookie("auth_session", $hash, $expiretime); 280 | } 281 | 282 | /* 283 | * Deletes the user's session based on hash 284 | * @param string $hash 285 | */ 286 | 287 | function deletesession($hash) 288 | { 289 | include("config.php"); 290 | include("lang.php"); 291 | 292 | $query = $this->mysqli->prepare("SELECT username FROM sessions WHERE hash=?"); 293 | $query->bind_param("s", $hash); 294 | $query->bind_result($username); 295 | $query->execute(); 296 | $query->store_result(); 297 | $count = $query->num_rows; 298 | $query->fetch(); 299 | $query->close(); 300 | 301 | if($count == 0) 302 | { 303 | // Hash doesn't exist 304 | 305 | $this->LogActivity("UNKNOWN", "AUTH_LOGOUT", "User session cookie deleted - Database session not deleted - Hash ({$hash}) didn't exist"); 306 | 307 | $this->errormsg[] = $lang[$loc]['auth']['deletesession_invalid']; 308 | 309 | setcookie("auth_session", $hash, time() - 3600); 310 | } 311 | else 312 | { 313 | // Hash exists, Delete all sessions for that username : 314 | 315 | $query = $this->mysqli->prepare("DELETE FROM sessions WHERE username=?"); 316 | $query->bind_param("s", $username); 317 | $query->execute(); 318 | $query->close(); 319 | 320 | $this->LogActivity($username, "AUTH_LOGOUT", "User session cookie deleted - Database session deleted - Hash ({$hash})"); 321 | 322 | setcookie("auth_session", $hash, time() - 3600); 323 | } 324 | } 325 | 326 | /* 327 | * Provides an associative array of user info based on session hash 328 | * @param string $hash 329 | * @return array $session 330 | */ 331 | 332 | function sessioninfo($hash) 333 | { 334 | include("config.php"); 335 | include("lang.php"); 336 | 337 | $query = $this->mysqli->prepare("SELECT uid, username, expiredate, ip FROM sessions WHERE hash=?"); 338 | $query->bind_param("s", $hash); 339 | $query->bind_result($session['uid'], $session['username'], $session['expiredate'], $session['ip']); 340 | $query->execute(); 341 | $query->store_result(); 342 | $count = $query->num_rows; 343 | $query->fetch(); 344 | $query->close(); 345 | 346 | if($count == 0) 347 | { 348 | // Hash doesn't exist 349 | 350 | $this->errormsg[] = $lang[$loc]['auth']['sessioninfo_invalid']; 351 | 352 | setcookie("auth_session", $hash, time() - 3600); 353 | 354 | return false; 355 | } 356 | else 357 | { 358 | // Hash exists 359 | 360 | return $session; 361 | } 362 | } 363 | 364 | /* 365 | * Checks if session is valid (Current IP = Stored IP + Current date < expire date) 366 | * @param string $hash 367 | * @return bool 368 | */ 369 | 370 | function checksession($hash) 371 | { 372 | $query = $this->mysqli->prepare("SELECT username, expiredate, ip FROM sessions WHERE hash=?"); 373 | $query->bind_param("s", $hash); 374 | $query->bind_result($username, $db_expiredate, $db_ip); 375 | $query->execute(); 376 | $query->store_result(); 377 | $count = $query->num_rows; 378 | $query->fetch(); 379 | $query->close(); 380 | 381 | if($count == 0) 382 | { 383 | // Hash doesn't exist 384 | 385 | setcookie("auth_session", $hash, time() - 3600); 386 | 387 | $this->LogActivity($username, "AUTH_CHECKSESSION", "User session cookie deleted - Hash ({$hash}) didn't exist"); 388 | 389 | return false; 390 | } 391 | else 392 | { 393 | if($_SERVER['REMOTE_ADDR'] != $db_ip) 394 | { 395 | // Hash exists, but IP has changed 396 | 397 | $query = $this->mysqli->prepare("DELETE FROM sessions WHERE username=?"); 398 | $query->bind_param("s", $username); 399 | $query->execute(); 400 | $query->close(); 401 | 402 | setcookie("auth_session", $hash, time() - 3600); 403 | 404 | $this->LogActivity($username, "AUTH_CHECKSESSION", "User session cookie deleted - IP Different ( DB : {$db_ip} / Current : " . $_SERVER['REMOTE_ADDR'] . " )"); 405 | 406 | return false; 407 | } 408 | else 409 | { 410 | $expiredate = strtotime($db_expiredate); 411 | $currentdate = strtotime(date("Y-m-d H:i:s")); 412 | 413 | if($currentdate > $expiredate) 414 | { 415 | // Hash exists, IP is the same, but session has expired 416 | 417 | $query = $this->mysqli->prepare("DELETE FROM sessions WHERE username=?"); 418 | $query->bind_param("s", $username); 419 | $query->execute(); 420 | $query->close(); 421 | 422 | setcookie("auth_session", $hash, time() - 3600); 423 | 424 | $this->LogActivity($username, "AUTH_CHECKSESSION", "User session cookie deleted - Session expired ( Expire date : {$db_expiredate} )"); 425 | 426 | return false; 427 | } 428 | else 429 | { 430 | // Hash exists, IP is the same, date < expiry date 431 | 432 | return true; 433 | } 434 | } 435 | } 436 | } 437 | 438 | /* 439 | * Returns a random string, length can be modified 440 | * @param int $length 441 | * @return string $key 442 | */ 443 | 444 | function randomkey($length = 10) 445 | { 446 | $chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890"; 447 | $key = ""; 448 | 449 | for($i = 0; $i < $length; $i++) 450 | { 451 | $key .= $chars{rand(0, strlen($chars) - 1)}; 452 | } 453 | 454 | return $key; 455 | } 456 | 457 | /* 458 | * Activate a user's account 459 | * @param string $username 460 | * @param string $key 461 | * @return boolean 462 | */ 463 | 464 | function activate($username, $key) 465 | { 466 | include("config.php"); 467 | include("lang.php"); 468 | 469 | // Input verification 470 | 471 | if(strlen($username) == 0) { $this->errormsg[] = $lang[$loc]['auth']['activate_username_empty']; return false; } 472 | elseif(strlen($username) > 30) { $this->errormsg[] = $lang[$loc]['auth']['activate_username_long']; return false; } 473 | elseif(strlen($username) < 3) { $this->errormsg[] = $lang[$loc]['auth']['activate_username_short']; return false; } 474 | elseif(strlen($key) == 0) { $this->errormsg[] = $lang[$loc]['auth']['activate_key_empty']; return false; } 475 | elseif(strlen($key) > 15) { $this->errormsg[] = $lang[$loc]['auth']['activate_key_long']; return false; } 476 | elseif(strlen($key) < 15) { $this->errormsg[] = $lang[$loc]['auth']['activate_key_short']; return false; } 477 | else 478 | { 479 | // Input is valid 480 | 481 | $query = $this->mysqli->prepare("SELECT isactive, activekey FROM users WHERE username=?"); 482 | $query->bind_param("s", $username); 483 | $query->bind_result($isactive, $activekey); 484 | $query->execute(); 485 | $query->store_result(); 486 | $count = $query->num_rows; 487 | $query->fetch(); 488 | $query->close(); 489 | 490 | if($count == 0) 491 | { 492 | // User doesn't exist 493 | 494 | $this->LogActivity("UNKNOWN", "AUTH_ACTIVATE_FAIL", "Username Incorrect : {$username}"); 495 | 496 | $this->errormsg[] = $lang[$loc]['auth']['activate_username_incorrect']; 497 | 498 | return false; 499 | } 500 | else 501 | { 502 | // User exists 503 | 504 | if($isactive == 1) 505 | { 506 | // Account is already activated 507 | 508 | $this->LogActivity($username, "AUTH_ACTIVATE_FAIL", "Account already activated"); 509 | 510 | $this->errormsg[] = $lang[$loc]['auth']['activate_account_activated']; 511 | 512 | return true; 513 | } 514 | else 515 | { 516 | // Account isn't activated 517 | 518 | if($key == $activekey) 519 | { 520 | // Activation keys match 521 | 522 | $new_isactive = 1; 523 | $new_activekey = "0"; 524 | 525 | $query = $this->mysqli->prepare("UPDATE users SET isactive=?, activekey=? WHERE username=?"); 526 | $query->bind_param("iss", $new_isactive, $new_activekey, $username); 527 | $query->execute(); 528 | $query->close(); 529 | 530 | $this->LogActivity($username, "AUTH_ACTIVATE_SUCCESS", "Activation successful. Key Entry deleted."); 531 | 532 | $this->successmsg[] = $lang[$loc]['auth']['activate_success']; 533 | 534 | return true; 535 | } 536 | else 537 | { 538 | // Activation Keys don't match 539 | 540 | $this->LogActivity($username, "AUTH_ACTIVATE_FAIL", "Activation keys don't match ( DB : {$activekey} / Given : {$key} )"); 541 | 542 | $this->errormsg[] = $lang[$loc]['auth']['activate_key_incorrect']; 543 | 544 | return false; 545 | } 546 | } 547 | } 548 | } 549 | } 550 | 551 | /* 552 | * Changes a user's password, providing the current password is known 553 | * @param string $username 554 | * @param string $currpass 555 | * @param string $newpass 556 | * @param string $verifynewpass 557 | * @return boolean 558 | */ 559 | 560 | function changepass($username, $currpass, $newpass, $verifynewpass) 561 | { 562 | include("config.php"); 563 | include("lang.php"); 564 | 565 | if(strlen($username) == 0) { $this->errormsg[] = $lang[$loc]['auth']['changepass_username_empty']; } 566 | elseif(strlen($username) > 30) { $this->errormsg[] = $lang[$loc]['auth']['changepass_username_long']; } 567 | elseif(strlen($username) < 3) { $this->errormsg[] = $lang[$loc]['auth']['changepass_username_short']; } 568 | if(strlen($currpass) == 0) { $this->errormsg[] = $lang[$loc]['auth']['changepass_currpass_empty']; } 569 | elseif(strlen($currpass) < 5) { $this->errormsg[] = $lang[$loc]['auth']['changepass_currpass_short']; } 570 | elseif(strlen($currpass) > 30) { $this->errormsg[] = $lang[$loc]['auth']['changepass_currpass_long']; } 571 | if(strlen($newpass) == 0) { $this->errormsg[] = $lang[$loc]['auth']['changepass_newpass_empty']; } 572 | elseif(strlen($newpass) < 5) { $this->errormsg[] = $lang[$loc]['auth']['changepass_newpass_short']; } 573 | elseif(strlen($newpass) > 30) { $this->errormsg[] = $lang[$loc]['auth']['changepass_newpass_long']; } 574 | elseif(strstr($newpass, $username)) { $this->errormsg[] = $lang[$loc]['auth']['changepass_password_username']; } 575 | elseif($newpass !== $verifynewpass) { $this->errormsg[] = $lang[$loc]['auth']['changepass_password_nomatch']; } 576 | 577 | if(count($this->errormsg) == 0) 578 | { 579 | $currpass = $this->hashpass($currpass); 580 | $newpass = $this->hashpass($newpass); 581 | 582 | $query = $this->mysqli->prepare("SELECT password FROM users WHERE username=?"); 583 | $query->bind_param("s", $username); 584 | $query->bind_result($db_currpass); 585 | $query->execute(); 586 | $query->store_result(); 587 | $count = $query->num_rows; 588 | $query->fetch(); 589 | $query->close(); 590 | 591 | if($count == 0) 592 | { 593 | $this->LogActivity("UNKNOWN", "AUTH_CHANGEPASS_FAIL", "Username Incorrect ({$username})"); 594 | 595 | $this->errormsg[] = $lang[$loc]['auth']['changepass_username_incorrect']; 596 | 597 | return false; 598 | } 599 | else 600 | { 601 | if($currpass == $db_currpass) 602 | { 603 | $query = $this->mysqli->prepare("UPDATE users SET password=? WHERE username=?"); 604 | $query->bind_param("ss", $newpass, $username); 605 | $query->execute(); 606 | $query->close(); 607 | 608 | $this->LogActivity($username, "AUTH_CHANGEPASS_SUCCESS", "Password changed"); 609 | 610 | $this->successmsg[] = $lang[$loc]['auth']['changepass_success']; 611 | 612 | return true; 613 | } 614 | else 615 | { 616 | $this->LogActivity($username, "AUTH_CHANGEPASS_FAIL", "Current Password Incorrect ( DB : {$db_currpass} / Given : {$currpass} )"); 617 | 618 | $this->errormsg[] = $lang[$loc]['auth']['changepass_currpass_incorrect']; 619 | 620 | return false; 621 | } 622 | } 623 | } 624 | else 625 | { 626 | return false; 627 | } 628 | } 629 | 630 | /* 631 | * Changes the stored email address based on username 632 | * @param string $username 633 | * @param string $email 634 | * @return boolean 635 | */ 636 | 637 | function changeemail($username, $email) 638 | { 639 | include("config.php"); 640 | include("lang.php"); 641 | 642 | if(strlen($username) == 0) { $this->errormsg[] = $lang[$loc]['auth']['changeemail_username_empty']; } 643 | elseif(strlen($username) > 30) { $this->errormsg[] = $lang[$loc]['auth']['changeemail_username_long']; } 644 | elseif(strlen($username) < 3) { $this->errormsg[] = $lang[$loc]['auth']['changeemail_username_short']; } 645 | if(strlen($email) == 0) { $this->errormsg[] = $lang[$loc]['auth']['changeemail_email_empty']; } 646 | elseif(strlen($email) > 100) { $this->errormsg[] = $lang[$loc]['auth']['changeemail_email_long']; } 647 | elseif(strlen($email) < 5) { $this->errormsg[] = $lang[$loc]['auth']['changeemail_email_short']; } 648 | elseif(!filter_var($email, FILTER_VALIDATE_EMAIL)) { $this->errormsg[] = $lang[$loc]['auth']['changeemail_email_invalid']; } 649 | 650 | if(count($this->errormsg) == 0) 651 | { 652 | $query = $this->mysqli->prepare("SELECT email FROM users WHERE username=?"); 653 | $query->bind_param("s", $username); 654 | $query->bind_result($db_email); 655 | $query->execute(); 656 | $query->store_result(); 657 | $count = $query->num_rows; 658 | $query->fetch(); 659 | $query->close(); 660 | 661 | if($count == 0) 662 | { 663 | $this->LogActivity("UNKNOWN", "AUTH_CHANGEEMAIL_FAIL", "Username Incorrect ({$username})"); 664 | 665 | $this->errormsg[] = $lang[$loc]['auth']['changeemail_username_incorrect']; 666 | 667 | return false; 668 | } 669 | else 670 | { 671 | if($email == $db_email) 672 | { 673 | $this->LogActivity($username, "AUTH_CHANGEEMAIL_FAIL", "Old and new email matched ({$email})"); 674 | 675 | $this->errormsg[] = $lang[$loc]['auth']['changeemail_email_match']; 676 | 677 | return false; 678 | } 679 | else 680 | { 681 | $query = $this->mysqli->prepare("UPDATE users SET email=? WHERE username=?"); 682 | $query->bind_param("ss", $email, $username); 683 | $query->execute(); 684 | $query->close(); 685 | 686 | $this->LogActivity($username, "AUTH_CHANGEEMAIL_SUCCESS", "Email changed from {$db_email} to {$email}"); 687 | 688 | $this->successmsg[] = $lang[$loc]['auth']['changeemail_success']; 689 | 690 | return true; 691 | } 692 | } 693 | } 694 | else 695 | { 696 | return false; 697 | } 698 | } 699 | 700 | /* 701 | * Give the user the ability to change their password if the current password is forgotten 702 | * by sending email to the email address associated to that user 703 | * @param string $username 704 | * @param string $email 705 | * @param string $key 706 | * @param string $newpass 707 | * @param string $verifynewpass 708 | * @return boolean 709 | */ 710 | 711 | function resetpass($username = '0', $email ='0', $key = '0', $newpass = '0', $verifynewpass = '0') 712 | { 713 | include("config.php"); 714 | include("lang.php"); 715 | 716 | $attcount = $this->getattempt($_SERVER['REMOTE_ADDR']); 717 | 718 | if($attcount >= $auth_conf['max_attempts']) 719 | { 720 | $this->errormsg[] = $lang[$loc]['auth']['resetpass_lockedout']; 721 | $this->errormsg[] = $lang[$loc]['auth']['resetpass_wait30']; 722 | 723 | return false; 724 | } 725 | else 726 | { 727 | if($username == '0' && $key == '0') 728 | { 729 | if(strlen($email) == 0) { $this->errormsg[] = $lang[$loc]['auth']['resetpass_email_empty']; } 730 | elseif(strlen($email) > 100) { $this->errormsg[] = $lang[$loc]['auth']['resetpass_email_long']; } 731 | elseif(strlen($email) < 5) { $this->errormsg[] = $lang[$loc]['auth']['resetpass_email_short']; } 732 | elseif(!filter_var($email, FILTER_VALIDATE_EMAIL)) { $this->errormsg[] = $lang[$loc]['auth']['resetpass_email_invalid']; } 733 | 734 | $resetkey = $this->randomkey(15); 735 | 736 | $query = $this->mysqli->prepare("SELECT username FROM users WHERE email=?"); 737 | $query->bind_param("s", $email); 738 | $query->bind_result($username); 739 | $query->execute(); 740 | $query->store_result(); 741 | $count = $query->num_rows; 742 | $query->fetch(); 743 | $query->close(); 744 | 745 | if($count == 0) 746 | { 747 | $this->errormsg[] = $lang[$loc]['auth']['resetpass_email_incorrect']; 748 | 749 | $attcount = $attcount + 1; 750 | $remaincount = $auth_conf['max_attempts'] - $attcount; 751 | 752 | $this->LogActivity("UNKNOWN", "AUTH_RESETPASS_FAIL", "Email incorrect ({$email})"); 753 | 754 | $this->errormsg[] = sprintf($lang[$loc]['auth']['resetpass_attempts_remaining'], $remaincount); 755 | 756 | $this->addattempt($_SERVER['REMOTE_ADDR']); 757 | 758 | return false; 759 | } 760 | else 761 | { 762 | $query = $this->mysqli->prepare("UPDATE users SET resetkey=? WHERE username=?"); 763 | $query->bind_param("ss", $resetkey, $username); 764 | $query->execute(); 765 | $query->close(); 766 | 767 | $message_from = $auth_conf['email_from']; 768 | $message_subj = $auth_conf['site_name'] . " - Password reset request !"; 769 | $message_cont = "Hello {$username}

"; 770 | $message_cont .= "You recently requested a password reset on " . $auth_conf['site_name'] . "
"; 771 | $message_cont .= "To proceed with the password reset, please click the following link :

"; 772 | $message_cont .= "Reset My Password"; 773 | $message_head = "From: {$message_from}" . "\r\n"; 774 | $message_head .= "MIME-Version: 1.0" . "\r\n"; 775 | $message_head .= "Content-type: text/html; charset=iso-8859-1" . "\r\n"; 776 | 777 | mail($email, $message_subj, $message_cont, $message_head); 778 | 779 | $this->LogActivity($username, "AUTH_RESETPASS_SUCCESS", "Reset pass request sent to {$email} ( Key : {$resetkey} )"); 780 | 781 | $this->successmsg[] = $lang[$loc]['auth']['resetpass_email_sent']; 782 | 783 | return true; 784 | } 785 | } 786 | else 787 | { 788 | // Reset Password 789 | 790 | if(strlen($key) == 0) { $this->errormsg[] = $lang[$loc]['auth']['resetpass_key_empty']; } 791 | elseif(strlen($key) < 15) { $this->errormsg[] = $lang[$loc]['auth']['resetpass_key_short']; } 792 | elseif(strlen($key) > 15) { $this->errormsg[] = $lang[$loc]['auth']['resetpass_key_long']; } 793 | if(strlen($newpass) == 0) { $this->errormsg[] = $lang[$loc]['auth']['resetpass_newpass_empty']; } 794 | elseif(strlen($newpass) > 30) { $this->errormsg[] = $lang[$loc]['auth']['resetpass_newpass_long']; } 795 | elseif(strlen($newpass) < 5) { $this->errormsg[] = $lang[$loc]['auth']['resetpass_newpass_short']; } 796 | elseif(strstr($newpass, $username)) { $this->errormsg[] = $lang[$loc]['auth']['resetpass_newpass_username']; } 797 | elseif($newpass !== $verifynewpass) { $this->errormsg[] = $lang[$loc]['auth']['resetpass_newpass_nomatch']; } 798 | 799 | if(count($this->errormsg) == 0) 800 | { 801 | $query = $this->mysqli->prepare("SELECT resetkey FROM users WHERE username=?"); 802 | $query->bind_param("s", $username); 803 | $query->bind_result($db_key); 804 | $query->execute(); 805 | $query->store_result(); 806 | $count = $query->num_rows; 807 | $query->fetch(); 808 | $query->close(); 809 | 810 | if($count == 0) 811 | { 812 | $this->errormsg[] = $lang[$loc]['auth']['resetpass_username_incorrect']; 813 | 814 | $attcount = $attcount + 1; 815 | $remaincount = $auth_conf['max_attempts'] - $attcount; 816 | 817 | $this->LogActivity("UNKNOWN", "AUTH_RESETPASS_FAIL", "Username incorrect ({$username})"); 818 | 819 | $this->errormsg[] = sprintf($lang[$loc]['auth']['resetpass_attempts_remaining'], $remaincount); 820 | 821 | $this->addattempt($_SERVER['REMOTE_ADDR']); 822 | 823 | return false; 824 | } 825 | else 826 | { 827 | if($key == $db_key) 828 | { 829 | $newpass = $this->hashpass($newpass); 830 | 831 | $resetkey = '0'; 832 | 833 | $query = $this->mysqli->prepare("UPDATE users SET password=?, resetkey=? WHERE username=?"); 834 | $query->bind_param("sss", $newpass, $resetkey, $username); 835 | $query->execute(); 836 | $query->close(); 837 | 838 | $this->LogActivity($username, "AUTH_RESETPASS_SUCCESS", "Password reset - Key reset"); 839 | 840 | $this->successmsg[] = $lang[$loc]['auth']['resetpass_success']; 841 | 842 | return true; 843 | } 844 | else 845 | { 846 | $this->errormsg[] = $lang[$loc]['auth']['resetpass_key_incorrect']; 847 | 848 | $attcount = $attcount + 1; 849 | $remaincount = 5 - $attcount; 850 | 851 | $this->LogActivity($username, "AUTH_RESETPASS_FAIL", "Key Incorrect ( DB : {$db_key} / Given : {$key} )"); 852 | 853 | $this->errormsg[] = sprintf($lang[$loc]['auth']['resetpass_attempts_remaining'], $remaincount); 854 | 855 | $this->addattempt($_SERVER['REMOTE_ADDR']); 856 | 857 | return false; 858 | } 859 | } 860 | } 861 | else 862 | { 863 | return false; 864 | } 865 | } 866 | } 867 | } 868 | 869 | /* 870 | * Checks if the reset key is correct for provided username 871 | * @param string $username 872 | * @param string $key 873 | * @return boolean 874 | */ 875 | 876 | function checkresetkey($username, $key) 877 | { 878 | include("config.php"); 879 | include("lang.php"); 880 | 881 | $attcount = $this->getattempt($_SERVER['REMOTE_ADDR']); 882 | 883 | if($attcount >= $auth_conf['max_attempts']) 884 | { 885 | $this->errormsg[] = $lang[$loc]['auth']['resetpass_lockedout']; 886 | $this->errormsg[] = $lang[$loc]['auth']['resetpass_wait30']; 887 | 888 | return false; 889 | } 890 | else 891 | { 892 | 893 | if(strlen($username) == 0) { return false; } 894 | elseif(strlen($username) > 30) { return false; } 895 | elseif(strlen($username) < 3) { return false; } 896 | elseif(strlen($key) == 0) { return false; } 897 | elseif(strlen($key) < 15) { return false; } 898 | elseif(strlen($key) > 15) { return false; } 899 | else 900 | { 901 | $query = $this->mysqli->prepare("SELECT resetkey FROM users WHERE username=?"); 902 | $query->bind_param("s", $username); 903 | $query->bind_result($db_key); 904 | $query->execute(); 905 | $query->store_result(); 906 | $count = $query->num_rows; 907 | $query->fetch(); 908 | $query->close(); 909 | 910 | if($count == 0) 911 | { 912 | $this->LogActivity("UNKNOWN", "AUTH_CHECKRESETKEY_FAIL", "Username doesn't exist ({$username})"); 913 | 914 | $this->addattempt($_SERVER['REMOTE_ADDR']); 915 | 916 | $this->errormsg[] = $lang[$loc]['auth']['checkresetkey_username_incorrect']; 917 | 918 | $attcount = $attcount + 1; 919 | $remaincount = $auth_conf['max_attempts'] - $attcount; 920 | 921 | $this->errormsg[] = sprintf($lang[$loc]['auth']['checkresetkey_attempts_remaining'], $remaincount); 922 | 923 | return false; 924 | } 925 | else 926 | { 927 | if($key == $db_key) 928 | { 929 | return true; 930 | } 931 | else 932 | { 933 | $this->LogActivity($username, "AUTH_CHECKRESETKEY_FAIL", "Key provided is different to DB key ( DB : {$db_key} / Given : {$key} )"); 934 | 935 | $this->addattempt($_SERVER['REMOTE_ADDR']); 936 | 937 | $this->errormsg[] = $lang[$loc]['auth']['checkresetkey_key_incorrect']; 938 | 939 | $attcount = $attcount + 1; 940 | $remaincount = $auth_conf['max_attempts'] - $attcount; 941 | 942 | $this->errormsg[] = sprintf($lang[$loc]['auth']['checkresetkey_attempts_remaining'], $remaincount); 943 | 944 | return false; 945 | } 946 | } 947 | } 948 | } 949 | } 950 | 951 | /* 952 | * Deletes a user's account. Requires user's password 953 | * @param string $username 954 | * @param string $password 955 | * @return boolean 956 | */ 957 | 958 | function deleteaccount($username, $password) 959 | { 960 | include("config.php"); 961 | include("lang.php"); 962 | 963 | if(strlen($username) == 0) { $this->errormsg[] = $lang[$loc]['auth']['deleteaccount_username_empty']; } 964 | elseif(strlen($username) > 30) { $this->errormsg[] = $lang[$loc]['auth']['deleteaccount_username_long']; } 965 | elseif(strlen($username) < 3) { $this->errormsg[] = $lang[$loc]['auth']['deleteaccount_username_short']; } 966 | if(strlen($password) == 0) { $this->errormsg[] = $lang[$loc]['auth']['deleteaccount_password_empty']; } 967 | elseif(strlen($password) > 30) { $this->errormsg[] = $lang[$loc]['auth']['deleteaccount_password_long']; } 968 | elseif(strlen($password) < 5) { $this->errormsg[] = $lang[$loc]['auth']['deleteaccount_password_short']; } 969 | 970 | if(count($this->errormsg) == 0) 971 | { 972 | $password = $this->hashpass($password); 973 | 974 | $query = $this->mysqli->prepare("SELECT password FROM users WHERE username=?"); 975 | $query->bind_param("s", $username); 976 | $query->bind_result($db_password); 977 | $query->execute(); 978 | $query->store_result(); 979 | $count = $query->num_rows; 980 | $query->fetch(); 981 | $query->close(); 982 | 983 | if($count == 0) 984 | { 985 | $this->LogActivity("UNKNOWN", "AUTH_DELETEACCOUNT_FAIL", "Username Incorrect ({$username})"); 986 | 987 | $this->errormsg[] = $lang[$loc]['auth']['deleteaccount_username_incorrect']; 988 | 989 | return false; 990 | } 991 | else 992 | { 993 | if($password == $db_password) 994 | { 995 | $query = $this->mysqli->prepare("DELETE FROM users WHERE username=?"); 996 | $query->bind_param("s", $username); 997 | $query->execute(); 998 | $query->close(); 999 | 1000 | $query = $this->mysqli->prepare("DELETE FROM sessions WHERE username=?"); 1001 | $query->bind_param("s", $username); 1002 | $query->execute(); 1003 | $query->close(); 1004 | 1005 | $this->LogActivity($username, "AUTH_DELETEACCOUNT_SUCCESS", "Account deleted - Sessions deleted"); 1006 | 1007 | $this->successmsg[] = $lang[$loc]['auth']['deleteaccount_success']; 1008 | 1009 | return true; 1010 | } 1011 | else 1012 | { 1013 | $this->LogActivity($username, "AUTH_DELETEACCOUNT_FAIL", "Password incorrect ( DB : {$db_password} / Given : {$password} )"); 1014 | 1015 | $this->errormsg[] = $lang[$loc]['auth']['deleteaccount_password_incorrect']; 1016 | 1017 | return false; 1018 | } 1019 | } 1020 | } 1021 | else 1022 | { 1023 | return false; 1024 | } 1025 | } 1026 | 1027 | /* 1028 | * Adds a new attempt to database based on user's IP 1029 | * @param string $ip 1030 | */ 1031 | 1032 | function addattempt($ip) 1033 | { 1034 | include("config.php"); 1035 | 1036 | $query = $this->mysqli->prepare("SELECT count FROM attempts WHERE ip = ?"); 1037 | $query->bind_param("s", $ip); 1038 | $query->bind_result($attempt_count); 1039 | $query->execute(); 1040 | $query->store_result(); 1041 | $count = $query->num_rows; 1042 | $query->fetch(); 1043 | $query->close(); 1044 | 1045 | if($count == 0) 1046 | { 1047 | // No record of this IP in attempts table already exists, create new 1048 | 1049 | $attempt_expiredate = date("Y-m-d H:i:s", strtotime($auth_conf['security_duration'])); 1050 | $attempt_count = 1; 1051 | 1052 | $query = $this->mysqli->prepare("INSERT INTO attempts (ip, count, expiredate) VALUES (?, ?, ?)"); 1053 | $query->bind_param("sis", $ip, $attempt_count, $attempt_expiredate); 1054 | $query->execute(); 1055 | $query->close(); 1056 | } 1057 | else 1058 | { 1059 | // IP Already exists in attempts table, add 1 to current count 1060 | 1061 | $attempt_expiredate = date("Y-m-d H:i:s", strtotime($auth_conf['security_duration'])); 1062 | $attempt_count = $attempt_count + 1; 1063 | 1064 | $query = $this->mysqli->prepare("UPDATE attempts SET count=?, expiredate=? WHERE ip=?"); 1065 | $query->bind_param("iss", $attempt_count, $attempt_expiredate, $ip); 1066 | $query->execute(); 1067 | $query->close(); 1068 | } 1069 | } 1070 | 1071 | /* 1072 | * Provides amount of attempts already in database based on user's IP 1073 | * @param string $ip 1074 | * @return int $attempt_count 1075 | */ 1076 | 1077 | function getattempt($ip) 1078 | { 1079 | $query = $this->mysqli->prepare("SELECT count FROM attempts WHERE ip = ?"); 1080 | $query->bind_param("s", $ip); 1081 | $query->bind_result($attempt_count); 1082 | $query->execute(); 1083 | $query->store_result(); 1084 | $count = $query->num_rows; 1085 | $query->fetch(); 1086 | $query->close(); 1087 | 1088 | if($count == 0) 1089 | { 1090 | $attempt_count = 0; 1091 | } 1092 | 1093 | return $attempt_count; 1094 | } 1095 | 1096 | /* 1097 | * Function used to remove expired attempt logs from database (Recommended as Cron Job) 1098 | */ 1099 | 1100 | function expireattempt() 1101 | { 1102 | $query = $this->mysqli->prepare("SELECT ip, expiredate FROM attempts"); 1103 | $query->bind_result($ip, $expiredate); 1104 | $query->execute(); 1105 | $query->store_result(); 1106 | $count = $query->num_rows; 1107 | 1108 | $curr_time = strtotime(date("Y-m-d H:i:s")); 1109 | 1110 | if($count != 0) 1111 | { 1112 | while($query->fetch()) 1113 | { 1114 | $attempt_expiredate = strtotime($expiredate); 1115 | 1116 | if($attempt_expiredate <= $curr_time) 1117 | { 1118 | $query2 = $this->mysqli->prepare("DELETE FROM attempts WHERE ip = ?"); 1119 | $query2->bind_param("s", $ip); 1120 | $query2->execute(); 1121 | $query2->close(); 1122 | } 1123 | } 1124 | } 1125 | } 1126 | 1127 | /* 1128 | * Logs users actions on the site to database for future viewing 1129 | * @param string $username 1130 | * @param string $action 1131 | * @param string $additionalinfo 1132 | * @return boolean 1133 | */ 1134 | 1135 | function LogActivity($username, $action, $additionalinfo = "none") 1136 | { 1137 | include("config.php"); 1138 | include("lang.php"); 1139 | 1140 | if(strlen($username) == 0) { $username = "GUEST"; } 1141 | elseif(strlen($username) < 3) { $this->errormsg[] = $lang[$loc]['auth']['logactivity_username_short']; return false; } 1142 | elseif(strlen($username) > 30) { $this->errormsg[] = $lang[$loc]['auth']['logactivity_username_long']; return false; } 1143 | 1144 | if(strlen($action) == 0) { $this->errormsg[] = $lang[$loc]['auth']['logactivity_action_empty']; return false; } 1145 | elseif(strlen($action) < 3) { $this->errormsg[] = $lang[$loc]['auth']['logactivity_action_short']; return false; } 1146 | elseif(strlen($action) > 100) { $this->errormsg[] = $lang[$loc]['auth']['logactivity_action_long']; return false; } 1147 | 1148 | if(strlen($additionalinfo) == 0) { $additionalinfo = "none"; } 1149 | elseif(strlen($additionalinfo) > 500) { $this->errormsg[] = $lang[$loc]['auth']['logactivity_addinfo_long']; return false; } 1150 | 1151 | if(count($this->errormsg) == 0) 1152 | { 1153 | $ip = $_SERVER['REMOTE_ADDR']; 1154 | $date = date("Y-m-d H:i:s"); 1155 | 1156 | $query = $this->mysqli->prepare("INSERT INTO activitylog (date, username, action, additionalinfo, ip) VALUES (?, ?, ?, ?, ?)"); 1157 | $query->bind_param("sssss", $date, $username, $action, $additionalinfo, $ip); 1158 | $query->execute(); 1159 | $query->close(); 1160 | 1161 | return true; 1162 | } 1163 | } 1164 | 1165 | /* 1166 | * Hash user's password with SHA512, base64_encode, ROT13 and salts ! 1167 | * @param string $password 1168 | * @return string $password 1169 | */ 1170 | 1171 | function hashpass($password) 1172 | { 1173 | include("config.php"); 1174 | 1175 | $password = hash("SHA512", base64_encode(str_rot13(hash("SHA512", str_rot13($auth_conf['salt_1'] . $password . $auth_conf['salt_2']))))); 1176 | return $password; 1177 | } 1178 | } 1179 | 1180 | ?> 1181 | -------------------------------------------------------------------------------- /auth.sql: -------------------------------------------------------------------------------- 1 | -- phpMyAdmin SQL Dump 2 | -- version 3.3.7 3 | -- http://www.phpmyadmin.net 4 | -- 5 | -- Serveur: localhost 6 | -- Généré le : Jeu 19 Janvier 2012 à 01:58 7 | -- Version du serveur: 5.1.58 8 | -- Version de PHP: 5.2.17 9 | 10 | SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO"; 11 | 12 | 13 | /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; 14 | /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; 15 | /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; 16 | /*!40101 SET NAMES utf8 */; 17 | 18 | -- 19 | -- Base de données: `u667856163_auth` 20 | -- 21 | 22 | -- -------------------------------------------------------- 23 | 24 | -- 25 | -- Structure de la table `activitylog` 26 | -- 27 | 28 | CREATE TABLE IF NOT EXISTS `activitylog` ( 29 | `id` int(11) NOT NULL AUTO_INCREMENT, 30 | `date` datetime NOT NULL, 31 | `username` varchar(30) NOT NULL, 32 | `action` varchar(100) NOT NULL, 33 | `additionalinfo` varchar(500) NOT NULL DEFAULT 'none', 34 | `ip` varchar(15) NOT NULL, 35 | PRIMARY KEY (`id`) 36 | ) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=11 ; 37 | 38 | -- -------------------------------------------------------- 39 | 40 | -- 41 | -- Structure de la table `attempts` 42 | -- 43 | 44 | CREATE TABLE IF NOT EXISTS `attempts` ( 45 | `ip` varchar(15) NOT NULL, 46 | `count` int(11) NOT NULL, 47 | `expiredate` datetime NOT NULL 48 | ) ENGINE=MyISAM DEFAULT CHARSET=latin1; 49 | 50 | -- -------------------------------------------------------- 51 | 52 | -- 53 | -- Structure de la table `sessions` 54 | -- 55 | 56 | CREATE TABLE IF NOT EXISTS `sessions` ( 57 | `id` int(11) NOT NULL AUTO_INCREMENT, 58 | `uid` int(11) NOT NULL, 59 | `username` varchar(30) NOT NULL, 60 | `hash` varchar(32) NOT NULL, 61 | `expiredate` datetime NOT NULL, 62 | `ip` varchar(15) NOT NULL, 63 | PRIMARY KEY (`id`) 64 | ) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=5 ; 65 | 66 | -- -------------------------------------------------------- 67 | 68 | -- 69 | -- Structure de la table `users` 70 | -- 71 | 72 | CREATE TABLE IF NOT EXISTS `users` ( 73 | `id` int(11) NOT NULL AUTO_INCREMENT, 74 | `username` varchar(30) NOT NULL, 75 | `password` varchar(128) NOT NULL, 76 | `email` varchar(100) NOT NULL, 77 | `isactive` tinyint(1) NOT NULL DEFAULT '0', 78 | `activekey` varchar(15) NOT NULL DEFAULT '0', 79 | `resetkey` varchar(15) NOT NULL DEFAULT '0', 80 | PRIMARY KEY (`id`) 81 | ) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=73 ; 82 | -------------------------------------------------------------------------------- /config.php: -------------------------------------------------------------------------------- 1 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /lang.php: -------------------------------------------------------------------------------- 1 | 245 | --------------------------------------------------------------------------------