fix: restore reads the options the web UI ticks

The web UI sends the restore options as the form field "data". The
param helpers looked up query parameters only, so /restore never saw
them and restored the shades alone, since 3.0.0. The helpers now take a
form field too.

/restore uses an upload once, and drops the file when the options aren't
JSON.

e2e: test_restore.py, a probe that the field is read and, with --reboot,
a settings-only round trip.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
cjkas 2026-10-28 21:02:39 +01:00
parent 0ee52d6d9f
commit 3d45ba59c1
8 changed files with 97 additions and 18 deletions

View file

@ -93,7 +93,11 @@ void registerHttpRoutes(AsyncWebServer &server) {
server.on(AsyncURIMatcher::exact("/restore"), HTTP_POST,
[](AsyncWebServerRequest *request) {
if(webServer.uploadSuccess) {
// An upload is restored once: a later /restore without a file must not
// find this one.
const bool uploaded = webServer.uploadSuccess;
webServer.uploadSuccess = false;
if(uploaded) {
restore_options_t opts;
if(asyncHasParam(request, "data")) {
String dataStr = asyncParam(request, "data");
@ -101,6 +105,7 @@ void registerHttpRoutes(AsyncWebServer &server) {
JsonDocument doc;
DeserializationError err = deserializeJson(doc, dataStr);
if(err) {
LittleFS.remove("/shades.tmp");
request->send(500, _encoding_json, "{\"status\":\"ERROR\",\"desc\":\"JSON parse error\"}");
return;
}