From f02c7e23f3e50f19956d107268f8c2c1af2df9cf Mon Sep 17 00:00:00 2001 From: Damian Schneider Date: Wed, 31 Dec 2025 16:33:31 +0100 Subject: [PATCH 1/2] add json validation to file uplod in UI and minify before upload. use sequential loading in edit.htm --- wled00/data/common.js | 20 +++++++++++++++----- wled00/data/edit.htm | 44 ++++++++++++++++++++++--------------------- 2 files changed, 38 insertions(+), 26 deletions(-) diff --git a/wled00/data/common.js b/wled00/data/common.js index 5f73c946d8..863584a67f 100644 --- a/wled00/data/common.js +++ b/wled00/data/common.js @@ -137,16 +137,26 @@ function showToast(text, error = false) { x.style.animation = 'none'; timeout = setTimeout(function(){ x.className = x.className.replace("show", ""); }, 2900); } -function uploadFile(fileObj, name) { +async function uploadFile(fileObj, name, callback) { + let file = fileObj.files?.[0]; // get first file, "?"" = optional chaining in case no file is selected + if (!file) { callback?.(false); return; } + if (/\.json$/i.test(name)) { // same as name.toLowerCase().endsWith('.json') + try { + const minified = JSON.stringify(JSON.parse(await file.text())); // validate and minify JSON + file = new Blob([minified], { type: file.type || "application/json" }); + } catch (err) { + if (!confirm("JSON invalid. Continue?")) { callback?.(false); return; } + // proceed with original file if invalid but user confirms + } + } var req = new XMLHttpRequest(); - req.addEventListener('load', function(){showToast(this.responseText,this.status >= 400)}); - req.addEventListener('error', function(e){showToast(e.stack,true);}); + req.addEventListener('load', function(){showToast(this.responseText,this.status >= 400); if(callback) callback(this.status < 400);}); + req.addEventListener('error', function(e){showToast(e.stack,true); if(callback) callback(false);}); req.open("POST", "/upload"); var formData = new FormData(); - formData.append("data", fileObj.files[0], name); + formData.append("data", file, name); req.send(formData); fileObj.value = ''; - return false; } // connect to WebSocket, use parent WS or open new, callback function gets passed the new WS object function connectWs(onOpen) { diff --git a/wled00/data/edit.htm b/wled00/data/edit.htm index d295639f55..3eddbe2f7b 100644 --- a/wled00/data/edit.htm +++ b/wled00/data/edit.htm @@ -5,12 +5,10 @@ - - - +
From a28b721037c1d403d8a1e4669b710a1ba91ad404 Mon Sep 17 00:00:00 2001 From: Damian Schneider Date: Wed, 31 Dec 2025 16:47:22 +0100 Subject: [PATCH 2/2] follow the rabbit. --- wled00/data/common.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wled00/data/common.js b/wled00/data/common.js index 863584a67f..a6223daa7c 100644 --- a/wled00/data/common.js +++ b/wled00/data/common.js @@ -151,7 +151,7 @@ async function uploadFile(fileObj, name, callback) { } var req = new XMLHttpRequest(); req.addEventListener('load', function(){showToast(this.responseText,this.status >= 400); if(callback) callback(this.status < 400);}); - req.addEventListener('error', function(e){showToast(e.stack,true); if(callback) callback(false);}); + req.addEventListener('error', function(e){showToast("Upload failed",true); if(callback) callback(false);}); req.open("POST", "/upload"); var formData = new FormData(); formData.append("data", file, name);