34784-vm/auth.php
Flatlogic Bot 0e7f6ab776 Edutask V1
2025-10-08 08:54:03 +00:00

225 lines
6.9 KiB
PHP

<?php
session_start();
require_once __DIR__ . '/db/config.php';
// --- Remember Me Logic ---
if (!isset($_SESSION['user_id']) && isset($_COOKIE['remember_me'])) {
loginViaCookie();
}
// --- Action Routing ---
header('Content-Type: application/json');
$action = $_POST['action'] ?? $_GET['action'] ?? '';
switch ($action) {
case 'login':
handle_login();
break;
case 'logout':
handle_logout();
break;
case 'check_session':
check_session();
break;
case 'register':
handle_register();
break;
default:
echo json_encode(['success' => 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
}
}