'Method not allowed']); exit; } $username = trim($_POST['username'] ?? ''); // Validate username if (!preg_match('/^[a-z0-9]{3,32}$/', $username)) { http_response_code(400); echo json_encode(['error' => 'Invalid username']); exit; } // Check user exists $db = new PDO('sqlite:/data/db/platform.sqlite'); $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $stmt = $db->prepare('SELECT id FROM users WHERE username = ?'); $stmt->execute([$username]); if (!$stmt->fetch()) { http_response_code(404); echo json_encode(['error' => 'User not found']); exit; } $htdocs = "/data/sites/{$username}/htdocs"; // Allowed file extensions $allowed = [ 'php','html','htm','css','js','json','txt','xml', 'png','jpg','jpeg','gif','webp','svg','ico', 'woff','woff2','ttf','eot','pdf','zip' ]; if (empty($_FILES['files'])) { http_response_code(400); echo json_encode(['error' => 'No files uploaded']); exit; } $uploaded = []; $errors = []; // Normalise $_FILES array for multiple uploads $files = $_FILES['files']; $count = is_array($files['name']) ? count($files['name']) : 1; for ($i = 0; $i < $count; $i++) { $name = is_array($files['name']) ? $files['name'][$i] : $files['name']; $tmp = is_array($files['tmp_name']) ? $files['tmp_name'][$i] : $files['tmp_name']; $error = is_array($files['error']) ? $files['error'][$i] : $files['error']; if ($error !== UPLOAD_ERR_OK) { $errors[] = "{$name}: upload error code {$error}"; continue; } // Sanitise filename — strip any path components $name = basename($name); $ext = strtolower(pathinfo($name, PATHINFO_EXTENSION)); if (!in_array($ext, $allowed)) { $errors[] = "{$name}: file type .{$ext} not allowed"; continue; } // Enforce 10 MB per file if (filesize($tmp) > 10 * 1024 * 1024) { $errors[] = "{$name}: exceeds 10 MB limit"; continue; } $dest = "{$htdocs}/{$name}"; if (move_uploaded_file($tmp, $dest)) { // Update files table $stmt = $db->prepare(' INSERT INTO files (username, filepath, updated_at) VALUES (?, ?, datetime("now")) ON CONFLICT(username, filepath) DO UPDATE SET updated_at=datetime("now") '); $stmt->execute([$username, $name]); $uploaded[] = $name; } else { $errors[] = "{$name}: failed to save file"; } } echo json_encode([ 'success' => count($uploaded) > 0, 'uploaded' => $uploaded, 'errors' => $errors ]);