| 976 | } |
| 977 | |
| 978 | void CrossPointWebServer::handleDelete() const { |
| 979 | // To ensure backwards compatibility, plain `path` is mapped |
| 980 | // to a single element JSON array. |
| 981 | bool hasPathArg = server->hasArg("path"); |
| 982 | bool hasPathsArg = server->hasArg("paths"); |
| 983 | // Check 'paths' or `path` argument is provided |
| 984 | if (!(hasPathArg || hasPathsArg)) { |
| 985 | server->send(400, "text/plain", "Missing `path` or `paths` argument"); |
| 986 | return; |
| 987 | } |
| 988 | if (hasPathArg && hasPathsArg) { |
| 989 | server->send(400, "text/plain", "Provide either 'path' or 'paths', not both"); |
| 990 | return; |
| 991 | } |
| 992 | |
| 993 | // Parse paths |
| 994 | String pathsArg; |
| 995 | JsonDocument doc; |
| 996 | DeserializationError error = DeserializationError(DeserializationError::Code::Ok); |
| 997 | if (hasPathsArg) { |
| 998 | pathsArg = server->arg("paths"); |
| 999 | error = deserializeJson(doc, pathsArg); |
| 1000 | } else { |
| 1001 | pathsArg = server->arg("path"); |
| 1002 | doc.add(pathsArg); |
| 1003 | } |
| 1004 | if (error) { |
| 1005 | server->send(400, "text/plain", "Invalid paths format"); |
| 1006 | return; |
| 1007 | } |
| 1008 | |
| 1009 | auto paths = doc.as<JsonArray>(); |
| 1010 | if (paths.isNull() || paths.size() == 0) { |
| 1011 | server->send(400, "text/plain", "No paths provided"); |
| 1012 | return; |
| 1013 | } |
| 1014 | |
| 1015 | // Iterate over paths and delete each item |
| 1016 | bool allSuccess = true; |
| 1017 | String failedItems; |
| 1018 | |
| 1019 | for (const auto& p : paths) { |
| 1020 | auto itemPath = p.as<String>(); |
| 1021 | |
| 1022 | // Validate path |
| 1023 | if (itemPath.isEmpty() || itemPath == "/") { |
| 1024 | failedItems += itemPath + " (cannot delete root); "; |
| 1025 | allSuccess = false; |
| 1026 | continue; |
| 1027 | } |
| 1028 | |
| 1029 | // Ensure path starts with / |
| 1030 | if (!itemPath.startsWith("/")) { |
| 1031 | itemPath = "/" + itemPath; |
| 1032 | } |
| 1033 | |
| 1034 | // Security check: prevent deletion of protected items |
| 1035 | const String itemName = itemPath.substring(itemPath.lastIndexOf('/') + 1); |
nothing calls this directly
no test coverage detected