require_once 'config/config.php'; class Auth { private $db; public function __construct() { $this->db = get_db_connection(); } public function login($username, $password) { try { $query = "SELECT id, username, email, password_hash, role FROM users WHERE username = :username OR email = :username"; $stmt = $this->db->prepare($query); $stmt->bindParam(':username', $username); $stmt->execute(); $user = $stmt->fetch(PDO::FETCH_ASSOC); if ($user) { $password_valid = false; // Try bcrypt first (password_hash format) if (password_verify($password, $user['password_hash'])) { $password_valid = true; } // Try SHA256 format (legacy support) elseif (strlen($user['password_hash']) === 64 && hash('sha256', $password) === $user['password_hash']) { $password_valid = true; // Upgrade to bcrypt for better security $new_hash = password_hash($password, PASSWORD_DEFAULT); $update_query = "UPDATE users SET password_hash = :new_hash WHERE id = :user_id"; $update_stmt = $this->db->prepare($update_query); $update_stmt->bindParam(':new_hash', $new_hash); $update_stmt->bindParam(':user_id', $user['id']); $update_stmt->execute(); } // Try plain text password (for development/migration) elseif ($password === $user['password_hash']) { $password_valid = true; // Upgrade to bcrypt $new_hash = password_hash($password, PASSWORD_DEFAULT); $update_query = "UPDATE users SET password_hash = :new_hash WHERE id = :user_id"; $update_stmt = $this->db->prepare($update_query); $update_stmt->bindParam(':new_hash', $new_hash); $update_stmt->bindParam(':user_id', $user['id']); $update_stmt->execute(); } if ($password_valid) { $_SESSION['user_id'] = $user['id']; $_SESSION['username'] = $user['username']; $_SESSION['email'] = $user['email']; $_SESSION['role'] = $user['role']; $_SESSION['login_time'] = time(); // Update last login $this->updateLastLogin($user['id']); return true; } } return false; } catch (PDOException $e) { error_log("Login error: " . $e->getMessage()); return false; } } public function logout() { session_destroy(); header("Location: " . BASE_URL . "login.php"); exit(); } public function isLoggedIn() { return isset($_SESSION['user_id']) && $this->isSessionValid(); } private function isSessionValid() { if (!isset($_SESSION['login_time'])) { return false; } // Check session timeout if (time() - $_SESSION['login_time'] > SESSION_TIMEOUT) { $this->logout(); return false; } return true; } public function requireLogin() { if (!$this->isLoggedIn()) { header("Location: " . BASE_URL . "login.php"); exit(); } } public function requireRole($required_roles) { $this->requireLogin(); if (!is_array($required_roles)) { $required_roles = [$required_roles]; } if (!in_array($_SESSION['role'], $required_roles)) { $_SESSION['error'] = "Access denied. Insufficient permissions."; header("Location: " . BASE_URL . "dashboard.php"); exit(); } } public function register($username, $email, $password, $role = 'user') { try { // Check if user exists $query = "SELECT id FROM users WHERE username = :username OR email = :email"; $stmt = $this->db->prepare($query); $stmt->bindParam(':username', $username); $stmt->bindParam(':email', $email); $stmt->execute(); if ($stmt->rowCount() > 0) { return false; // User already exists } // Create user $password_hash = password_hash($password, PASSWORD_DEFAULT); $query = "INSERT INTO users (username, email, password_hash, role, created_at) VALUES (:username, :email, :password_hash, :role, NOW())"; $stmt = $this->db->prepare($query); $stmt->bindParam(':username', $username); $stmt->bindParam(':email', $email); $stmt->bindParam(':password_hash', $password_hash); $stmt->bindParam(':role', $role); return $stmt->execute(); } catch (PDOException $e) { error_log("Registration error: " . $e->getMessage()); return false; } } public function changePassword($user_id, $current_password, $new_password) { try { // Verify current password $query = "SELECT password_hash FROM users WHERE id = :user_id"; $stmt = $this->db->prepare($query); $stmt->bindParam(':user_id', $user_id); $stmt->execute(); $user = $stmt->fetch(PDO::FETCH_ASSOC); if (!$user || !password_verify($current_password, $user['password_hash'])) { return false; } // Update password $new_password_hash = password_hash($new_password, PASSWORD_DEFAULT); $query = "UPDATE users SET password_hash = :password_hash, updated_at = NOW() WHERE id = :user_id"; $stmt = $this->db->prepare($query); $stmt->bindParam(':password_hash', $new_password_hash); $stmt->bindParam(':user_id', $user_id); return $stmt->execute(); } catch (PDOException $e) { error_log("Change password error: " . $e->getMessage()); return false; } } private function updateLastLogin($user_id) { try { $query = "UPDATE users SET updated_at = NOW() WHERE id = :user_id"; $stmt = $this->db->prepare($query); $stmt->bindParam(':user_id', $user_id); $stmt->execute(); } catch (PDOException $e) { error_log("Update last login error: " . $e->getMessage()); } } public function getUserById($user_id) { try { $query = "SELECT id, username, email, role, created_at FROM users WHERE id = :user_id"; $stmt = $this->db->prepare($query); $stmt->bindParam(':user_id', $user_id); $stmt->execute(); return $stmt->fetch(PDO::FETCH_ASSOC); } catch (PDOException $e) { error_log("Get user error: " . $e->getMessage()); return false; } } } ?>