2019-11-27 22:28:13 +01:00
<!DOCTYPE html>
2020-12-23 21:43:30 +01:00
< html lang = "en" >
2019-11-27 22:28:13 +01:00
< head >
2023-10-04 21:37:10 +02:00
< meta content = "width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" name = "viewport" >
2020-05-17 21:39:57 +02:00
< meta charset = "utf-8" >
2019-11-27 22:28:13 +01:00
< title > Misc Settings< / title >
< script >
2021-07-14 23:10:19 +02:00
var d = document;
2023-06-04 18:40:29 +02:00
var loc = false, locip, locproto = "http:";
2022-03-02 15:41:31 +01:00
function H() { window.open("https://kno.wled.ge/features/settings/#security-settings"); }
2023-06-04 18:40:29 +02:00
function B() { window.open(getURL("/settings"),"_self"); }
function U() { window.open(getURL("/update"),"_self"); }
2022-03-02 15:41:31 +01:00
function gId(s) { return d.getElementById(s); }
function isObj(o) { return (o & & typeof o === 'object' & & !Array.isArray(o)); }
2022-07-17 15:58:41 +02:00
// https://www.educative.io/edpresso/how-to-dynamically-load-a-js-file-in-javascript
function loadJS(FILE_URL, async = true) {
let scE = d.createElement("script");
scE.setAttribute("src", FILE_URL);
scE.setAttribute("type", "text/javascript");
scE.setAttribute("async", async);
d.body.appendChild(scE);
// success event
scE.addEventListener("load", () => {
//console.log("File loaded");
GetV();
2022-08-05 12:09:13 +02:00
setBckFilename(gId("bckcfg"));
setBckFilename(gId("bckpresets"));
2022-07-17 15:58:41 +02:00
});
// error event
scE.addEventListener("error", (ev) => {
console.log("Error on loading file", ev);
alert("Loading of configuration script failed.\nIncomplete page data!");
});
}
2021-07-14 23:10:19 +02:00
var timeout;
function showToast(text, error = false)
{
var x = gId("toast");
x.innerHTML = text;
2021-10-04 00:41:50 +02:00
x.classList.add(error ? "error":"show");
2021-07-14 23:10:19 +02:00
clearTimeout(timeout);
x.style.animation = 'none';
2021-10-04 00:41:50 +02:00
timeout = setTimeout(function(){ x.classList.remove("show"); }, 2900);
2021-07-14 23:10:19 +02:00
}
2021-07-15 09:24:10 +02:00
function uploadFile(fO,name) {
2021-07-14 23:10:19 +02:00
var req = new XMLHttpRequest();
2021-09-21 23:37:35 +02:00
req.addEventListener('load', function(){showToast(this.responseText,this.status >= 400)});
2021-07-14 23:10:19 +02:00
req.addEventListener('error', function(e){showToast(e.stack,true);});
2023-06-08 09:41:38 +02:00
req.open("POST", getURL("/upload"));
2021-07-14 23:10:19 +02:00
var formData = new FormData();
2021-07-15 09:24:10 +02:00
formData.append("data", fO.files[0], name);
2021-07-14 23:10:19 +02:00
req.send(formData);
2021-07-15 09:24:10 +02:00
fO.value = '';
2021-07-14 23:10:19 +02:00
return false;
2023-01-16 22:12:02 +01:00
}
2022-03-02 15:41:31 +01:00
function checkNum(o) {
2022-04-07 21:54:55 +02:00
const specialkeys = ["Backspace", "Tab", "Enter", "Shift", "Control", "Alt", "Pause", "CapsLock", "Escape", "Space", "PageUp", "PageDown", "End", "Home", "ArrowLeft", "ArrowUp", "ArrowRight", "ArrowDown", "Insert", "Delete"];
// true if key is a number or a special key
if(event.key.match(/[0-9]/) || specialkeys.includes(event.key)) return true;
2022-03-02 15:41:31 +01:00
event.preventDefault();
return false;
}
2022-08-05 12:09:13 +02:00
function setBckFilename(x) {
x.setAttribute("download","wled_" + x.getAttribute("download") + (sd=="WLED"?"":("_" +sd)));
}
2022-07-17 15:58:41 +02:00
function S() {
2023-06-07 21:37:54 +02:00
let l = window.location;
if (l.protocol == "file:") {
2022-07-17 15:58:41 +02:00
loc = true;
locip = localStorage.getItem('locIp');
if (!locip) {
locip = prompt("File Mode. Please enter WLED IP!");
localStorage.setItem('locIp', locip);
}
2023-06-04 18:40:29 +02:00
} else {
// detect reverse proxy
2023-06-07 21:37:54 +02:00
let path = l.pathname;
2023-06-04 18:40:29 +02:00
let paths = path.slice(1,path.endsWith('/')?-1:undefined).split("/");
if (paths.length > 2) {
2023-11-08 18:40:52 +01:00
paths.pop(); // remove "sec"
paths.pop(); // remove "settings"
2023-06-07 21:37:54 +02:00
locproto = l.protocol;
2023-06-04 18:40:29 +02:00
loc = true;
2023-11-08 18:40:52 +01:00
locip = l.hostname + (l.port ? ":" + l.port : "") + "/" + paths.join('/');
2023-06-04 18:40:29 +02:00
}
2022-07-17 15:58:41 +02:00
}
2023-06-08 09:41:38 +02:00
if (loc) {
gId("bckcfg").setAttribute('href',getURL(gId("bckcfg").pathname));
gId("bckpresets").setAttribute('href',getURL(gId("bckpresets").pathname));
}
2023-06-04 18:40:29 +02:00
loadJS(getURL('/settings/s.js?p=6'), false); // If we set async false, file is loaded and executed, then next statement is processed
if (loc) d.Sf.action = getURL('/settings/sec');
}
function getURL(path) {
return (loc ? locproto + "//" + locip : "") + path;
2019-11-27 22:28:13 +01:00
}
< / script >
< style >
2020-06-10 12:45:44 +02:00
@import url("style.css");
2019-11-27 22:28:13 +01:00
< / style >
< / head >
2022-07-17 15:58:41 +02:00
< body onload = "S()" >
2019-11-27 22:28:13 +01:00
< form id = "form_s" name = "Sf" method = "post" >
2021-03-05 09:50:59 +01:00
< div class = "toprow" >
2019-11-27 22:28:13 +01:00
< div class = "helpB" > < button type = "button" onclick = "H()" > ?< / button > < / div >
2022-03-01 23:37:28 +01:00
< button type = "button" onclick = "B()" > Back< / button > < button type = "submit" > Save< / button > < hr >
2021-03-05 09:50:59 +01:00
< / div >
2019-11-27 22:28:13 +01:00
< h2 > Security & Update setup< / h2 >
2022-04-07 21:54:55 +02:00
Settings PIN: < input type = "password" id = "PIN" name = "PIN" size = "4" maxlength = "4" minlength = "4" onkeydown = "checkNum(this)" pattern = "[0-9]*" inputmode = "numeric" title = "Please enter a 4 digit number" > < br >
2023-05-30 19:36:14 +02:00
< div class = "warn" > ⚠ Unencrypted transmission. Be prudent when selecting PIN, do NOT use your banking, door, SIM, etc. pin!< / div > < br >
2019-11-27 22:28:13 +01:00
Lock wireless (OTA) software update: < input type = "checkbox" name = "NO" > < br >
Passphrase: < input type = "password" name = "OP" maxlength = "32" > < br >
To enable OTA, for security reasons you need to also enter the correct password!< br >
The password should be changed when OTA is enabled.< br >
< b > Disable OTA when not in use, otherwise an attacker can reflash device software!< / b > < br >
< i > Settings on this page are only changable if OTA lock is disabled!< / i > < br >
Deny access to WiFi settings if locked: < input type = "checkbox" name = "OW" > < br > < br >
Factory reset: < input type = "checkbox" name = "RS" > < br >
2021-04-15 10:55:22 +02:00
All settings and presets will be erased.< br > < br >
2023-05-30 19:36:14 +02:00
< div class = "warn" > ⚠ Unencrypted transmission. An attacker on the same network can intercept form data!< / div >
2021-08-19 21:57:04 +02:00
< hr >
2019-11-27 22:28:13 +01:00
< h3 > Software Update< / h3 >
< button type = "button" onclick = "U()" > Manual OTA Update< / button > < br >
2022-03-01 23:37:28 +01:00
Enable ArduinoOTA: < input type = "checkbox" name = "AO" >
< hr >
2021-07-25 22:44:26 +02:00
< h3 > Backup & Restore< / h3 >
2022-08-05 12:09:13 +02:00
< a class = "btn lnk" id = "bckcfg" href = "/presets.json" download = "presets" > Backup presets< / a > < br >
2022-05-01 22:09:40 +02:00
< div > Restore presets< br > < input type = "file" name = "data" accept = ".json" > < button type = "button" onclick = "uploadFile(d.Sf.data,'/presets.json');" > Upload< / button > < br > < / div > < br >
2022-08-05 12:09:13 +02:00
< a class = "btn lnk" id = "bckpresets" href = "/cfg.json" download = "cfg" > Backup configuration< / a > < br >
2022-05-01 22:09:40 +02:00
< div > Restore configuration< br > < input type = "file" name = "data2" accept = ".json" > < button type = "button" onclick = "uploadFile(d.Sf.data2,'/cfg.json');" > Upload< / button > < br > < / div >
2023-05-30 19:36:14 +02:00
< div class = "warn" > ⚠ Restoring presets/configuration will OVERWRITE your current presets/configuration.< br >
2021-07-26 00:10:36 +02:00
Incorrect configuration may require a factory reset or re-flashing of your ESP.< / div >
2021-07-25 22:44:26 +02:00
For security reasons, passwords are not backed up.
2022-03-01 23:37:28 +01:00
< hr >
2019-11-27 22:28:13 +01:00
< h3 > About< / h3 >
2020-06-08 19:59:40 +02:00
< a href = "https://github.com/Aircoookie/WLED/" target = "_blank" > WLED< / a > version ##VERSION##<!-- Autoreplaced from package.json --> < br > < br >
2021-01-05 21:35:07 +01:00
< a href = "https://github.com/Aircoookie/WLED/wiki/Contributors-and-credits" target = "_blank" > Contributors, dependencies and special thanks< / a > < br >
2019-11-27 22:28:13 +01:00
A huge thank you to everyone who helped me create WLED!< br > < br >
2023-01-03 17:36:24 +01:00
(c) 2016-2023 Christian Schwinne < br >
2020-11-10 13:30:42 +01:00
< i > Licensed under the < a href = "https://github.com/Aircoookie/WLED/blob/master/LICENSE" target = "_blank" > MIT license< / a > < / i > < br > < br >
2020-05-02 01:59:41 +02:00
Server message: < span class = "sip" > Response error! < / span > < hr >
2021-07-14 23:10:19 +02:00
< div id = "toast" > < / div >
2022-03-01 23:37:28 +01:00
< button type = "button" onclick = "B()" > Back< / button > < button type = "submit" > Save< / button >
2019-11-27 22:28:13 +01:00
< / form >
< / body >
< / html >