false, 'message' => 'Invalid action']); break; } function handle_login() { $username = $_POST['username'] ?? ''; $password = $_POST['password'] ?? ''; $remember = isset($_POST['remember']); $demo_users = ['admin', 'guru', 'siswa']; if (empty($username) || empty($password)) { echo json_encode(['success' => false, 'message' => 'Username and password are required.']); return; } try { $pdo = db(); $stmt = $pdo->prepare("SELECT * FROM users WHERE username = :username"); $stmt->execute(['username' => $username]); $user = $stmt->fetch(); if ($user && password_verify($password, $user['password'])) { // For demo users, we don't regenerate the session ID to allow multiple logins. // For regular users, we do it for security. if (!in_array($username, $demo_users)) { session_regenerate_id(true); } $_SESSION['loggedin'] = true; $_SESSION['user_id'] = $user['id']; $_SESSION['username'] = $user['username']; $_SESSION['role'] = $user['role']; if ($remember) { setRememberMeCookie($user['id']); } echo json_encode([ 'success' => true, 'message' => 'Login successful!', 'user' => [ 'username' => $user['username'], 'role' => $user['role'] ] ]); } else { echo json_encode(['success' => false, 'message' => 'Invalid username or password.']); } } catch (PDOException $e) { echo json_encode(['success' => false, 'message' => 'Database error: ' . $e->getMessage()]); } } function handle_register() { $username = $_POST['username'] ?? ''; $password = $_POST['password'] ?? ''; if (empty($username) || empty($password)) { echo json_encode(['success' => false, 'message' => 'Username dan password tidak boleh kosong.']); return; } if (strlen($password) < 6) { echo json_encode(['success' => false, 'message' => 'Password minimal harus 6 karakter.']); return; } if (!preg_match('/^[a-zA-Z0-9_]+$/', $username)) { echo json_encode(['success' => false, 'message' => 'Username hanya boleh berisi huruf, angka, dan underscore.']); return; } try { $pdo = db(); $stmt = $pdo->prepare("SELECT id FROM users WHERE username = :username"); $stmt->execute(['username' => $username]); if ($stmt->fetch()) { echo json_encode(['success' => false, 'message' => 'Username sudah digunakan. Silakan pilih yang lain.']); return; } $hashed_password = password_hash($password, PASSWORD_DEFAULT); $stmt = $pdo->prepare("INSERT INTO users (username, password, role) VALUES (:username, :password, 'siswa')"); $stmt->execute([ 'username' => $username, 'password' => $hashed_password ]); echo json_encode(['success' => true, 'message' => 'Registrasi berhasil! Anda akan dialihkan ke halaman login.']); } catch (PDOException $e) { echo json_encode(['success' => false, 'message' => 'Terjadi kesalahan pada database.']); } } function handle_logout() { if (isset($_SESSION['user_id'])) { clearRememberMeCookie($_SESSION['user_id']); } session_unset(); session_destroy(); echo json_encode(['success' => true, 'message' => 'Logged out successfully.']); } function check_session() { if (isset($_SESSION['user_id'])) { echo json_encode([ 'success' => true, 'loggedIn' => true, 'user' => [ 'username' => $_SESSION['username'], 'role' => $_SESSION['role'] ] ]); } else { echo json_encode(['success' => true, 'loggedIn' => false]); } } // --- Remember Me Helper Functions --- function setRememberMeCookie($userId) { try { $token = bin2hex(random_bytes(32)); $hashed_token = hash('sha256', $token); $pdo = db(); $stmt = $pdo->prepare("UPDATE users SET remember_token = :token WHERE id = :id"); $stmt->execute(['token' => $hashed_token, 'id' => $userId]); $cookie_value = $userId . ':' . $token; $expiry = time() + (86400 * 30); // 30 days setcookie('remember_me', $cookie_value, [ 'expires' => $expiry, 'path' => '/', 'domain' => '', // current domain 'secure' => isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off', 'httponly' => true, 'samesite' => 'Lax' ]); } catch (Exception $e) { // Silently fail on cookie setting error } } function clearRememberMeCookie($userId) { try { $pdo = db(); $stmt = $pdo->prepare("UPDATE users SET remember_token = NULL WHERE id = :id"); $stmt->execute(['id' => $userId]); if (isset($_COOKIE['remember_me'])) { unset($_COOKIE['remember_me']); setcookie('remember_me', '', time() - 3600, '/'); } } catch (Exception $e) { // Silently fail } } function loginViaCookie() { $cookie = $_COOKIE['remember_me'] ?? ''; if (!$cookie) return; $parts = explode(':', $cookie); if (count($parts) !== 2) return; list($userId, $token) = $parts; if (empty($userId) || empty($token)) return; try { $pdo = db(); $stmt = $pdo->prepare("SELECT * FROM users WHERE id = :id"); $stmt->execute(['id' => $userId]); $user = $stmt->fetch(); if ($user && !empty($user['remember_token'])) { $hashed_token_from_cookie = hash('sha256', $token); if (hash_equals($user['remember_token'], $hashed_token_from_cookie)) { // Log user in session_regenerate_id(true); $_SESSION['loggedin'] = true; $_SESSION['user_id'] = $user['id']; $_SESSION['username'] = $user['username']; $_SESSION['role'] = $user['role']; // Security: Rotate token setRememberMeCookie($user['id']); } } } catch (Exception $e) { // Silently fail } }