diff --git a/backend/api/index.php b/backend/api/index.php index 9137913..b2f4099 100644 --- a/backend/api/index.php +++ b/backend/api/index.php @@ -1,4 +1,5 @@ 'Unauthorized']); + exit; + } +} + +$method = $_SERVER['REQUEST_METHOD']; $id = $segments[1] ?? null; try { switch ($resource) { + case 'session': + handleSession($method, $db); + break; + case 'settings': + handleSettings($method, $db); + break; case 'teams': handleTeams($method, $id, $db); break; @@ -51,6 +67,110 @@ try { echo json_encode(['error' => $e->getMessage()]); } +function handleSession($method, $db) { + $loggedin = isset($_SESSION['neptune_loggedin']) && $_SESSION['neptune_loggedin'] === true; + if ($loggedin) { + $role = $_SESSION['neptune_role'] ?? 'user'; + $stmt = $db->prepare("SELECT COUNT(*) as c FROM neptune_users WHERE role='admin'"); + $stmt->execute(); + $adminCount = $stmt->fetch()['c']; + echo json_encode([ + 'loggedin' => true, + 'username' => $_SESSION['neptune_username'] ?? 'Unknown', + 'role' => $role, + 'admin_count' => (int)$adminCount + ]); + } else { + echo json_encode(['loggedin' => false]); + } +} + +function handleSettings($method, $db) { + $role = $_SESSION['neptune_role'] ?? 'user'; + if ($method === 'GET') { + if ($role !== 'admin') { + http_response_code(403); + echo json_encode(['error' => 'Admins only']); + return; + } + $users = $db->query("SELECT id, username, user_token, email, role, created_at FROM neptune_users ORDER BY created_at ASC")->fetchAll(); + echo json_encode($users); + } elseif ($method === 'POST') { + if ($role !== 'admin') { + http_response_code(403); + echo json_encode(['error' => 'Admins only']); + return; + } + $data = json_decode(file_get_contents('php://input'), true); + $user_token = $data['user_token'] ?? ''; + if (!$user_token) { + http_response_code(400); + echo json_encode(['error' => 'user_token required']); + return; + } + // Validate the token with Jakach Auth + $check_url = "https://auth.jakach.ch/api/auth/check_auth_key.php?auth_token=" . urlencode($user_token); + $ch = curl_init(); + curl_setopt($ch, CURLOPT_URL, $check_url); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch, CURLOPT_TIMEOUT, 10); + $response = curl_exec($ch); + $http = curl_getinfo($ch, CURLINFO_HTTP_CODE); + curl_close($ch); + + if ($http !== 200 || !$response) { + http_response_code(400); + echo json_encode(['error' => 'Failed to validate token']); + return; + } + $info = json_decode($response, true); + if (!isset($info['status']) || $info['status'] !== 'success') { + http_response_code(400); + echo json_encode(['error' => 'Invalid token']); + return; + } + + $stmt = $db->prepare("SELECT COUNT(*) as c FROM neptune_users WHERE user_token = ?"); + $stmt->execute([$user_token]); + if ($stmt->fetch()['c'] > 0) { + http_response_code(400); + echo json_encode(['error' => 'User already exists']); + return; + } + + $stmt = $db->prepare("INSERT INTO neptune_users (user_token, username, email, role) VALUES (?, ?, ?, 'user')"); + $stmt->execute([$user_token, $info['username'], $info['email'] ?? '']); + echo json_encode(['status' => 'success', 'msg' => 'User added']); + } elseif ($method === 'DELETE') { + if ($role !== 'admin') { + http_response_code(403); + echo json_encode(['error' => 'Admins only']); + return; + } + $data = json_decode(file_get_contents('php://input'), true); + $id = $data['id'] ?? null; + if (!$id) { + http_response_code(400); + echo json_encode(['error' => 'id required']); + return; + } + // Prevent deleting the last admin + $stmt = $db->prepare("SELECT role FROM neptune_users WHERE id = ?"); + $stmt->execute([$id]); + $user = $stmt->fetch(); + if ($user && $user['role'] === 'admin') { + $adminCount = $db->query("SELECT COUNT(*) as c FROM neptune_users WHERE role='admin'")->fetch()['c']; + if ($adminCount <= 1) { + http_response_code(400); + echo json_encode(['error' => 'Cannot delete the last admin']); + return; + } + } + $db->prepare("DELETE FROM neptune_users WHERE id = ?")->execute([$id]); + echo json_encode(['status' => 'success']); + } +} + function handleTeams($method, $id, $db) { switch ($method) { case 'GET': diff --git a/backend/config/database.php b/backend/config/database.php index 608986d..2dd82ed 100644 --- a/backend/config/database.php +++ b/backend/config/database.php @@ -30,4 +30,12 @@ function migrate($db) { z_index INT DEFAULT 0, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP )"); + $db->exec("CREATE TABLE IF NOT EXISTS neptune_users ( + id INT AUTO_INCREMENT PRIMARY KEY, + user_token VARCHAR(255) NOT NULL UNIQUE, + username VARCHAR(255) NOT NULL, + email VARCHAR(255) DEFAULT '', + role ENUM('admin','user') DEFAULT 'user', + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP + )"); } \ No newline at end of file diff --git a/backend/login.php b/backend/login.php new file mode 100644 index 0000000..8e7db2d --- /dev/null +++ b/backend/login.php @@ -0,0 +1,107 @@ +prepare("SELECT * FROM neptune_users WHERE user_token = ?"); + $stmt->execute([$user_token]); + $user = $stmt->fetch(); + + if ($user) { + $_SESSION['neptune_loggedin'] = true; + $_SESSION['neptune_user_token'] = $user['user_token']; + $_SESSION['neptune_username'] = $user['username']; + $_SESSION['neptune_role'] = $user['role']; + header('Location: /'); + exit; + } else { + // First user becomes admin + $count = $db->query("SELECT COUNT(*) as c FROM neptune_users")->fetch()['c']; + $role = ($count == 0) ? 'admin' : 'user'; + + $stmt = $db->prepare("INSERT INTO neptune_users (user_token, username, email, role) VALUES (?, ?, ?, ?)"); + $stmt->execute([$user_token, $username, $email, $role]); + + $_SESSION['neptune_loggedin'] = true; + $_SESSION['neptune_user_token'] = $user_token; + $_SESSION['neptune_username'] = $username; + $_SESSION['neptune_role'] = $role; + header('Location: /'); + exit; + } + } else { + $error = 'Authentication failed: ' . ($data['msg'] ?? 'unknown error'); + } + } +} +?> + + +
+ + +Cybersecurity Incident Journal
+ + +