mirror of
https://github.com/xoseperez/espurna.git
synced 2026-03-10 02:07:03 +01:00
Merge branch 'dev' into sensors
This commit is contained in:
@@ -50,10 +50,6 @@ h2 {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.content {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.page {
|
||||
margin-top: 10px;
|
||||
}
|
||||
@@ -98,16 +94,12 @@ div.center {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#credentials {
|
||||
font-size: 200%;
|
||||
height: 100px;
|
||||
left: 50%;
|
||||
margin-left: -200px;
|
||||
margin-top: -50px;
|
||||
position: fixed;
|
||||
text-align: center;
|
||||
top: 50%;
|
||||
width: 400px;
|
||||
#password .content {
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
#layout .content {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
div.state {
|
||||
@@ -206,6 +198,10 @@ div.state {
|
||||
background: rgb(255, 128, 0); /* orange */
|
||||
}
|
||||
|
||||
.button-generate-password {
|
||||
background: rgb(66, 184, 221); /* blue */
|
||||
}
|
||||
|
||||
.button-upgrade-browse,
|
||||
.button-clear-filters,
|
||||
.button-clear-messages,
|
||||
@@ -448,3 +444,53 @@ table.dataTable.display tbody td {
|
||||
height: 400px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
Password input controls
|
||||
-------------------------------------------------------------------------- */
|
||||
.password-reveal {
|
||||
font-family: EmojiSymbols,Segoe UI Symbol;
|
||||
background: rgba(0,0,0,0);
|
||||
display: inline-block;
|
||||
float: right;
|
||||
z-index: 50;
|
||||
margin-top: 6px;
|
||||
margin-left: -30px;
|
||||
vertical-align: middle;
|
||||
font-size: 1.2em;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.password-reveal:after {
|
||||
content: "👁";
|
||||
}
|
||||
|
||||
input[type="password"] + .password-reveal {
|
||||
color: rgba(205, 205, 205, 0.3);
|
||||
}
|
||||
|
||||
input[type="text"] + .password-reveal {
|
||||
color: rgba(66, 184, 221, 0.8);
|
||||
}
|
||||
|
||||
.no-select {
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
input::-ms-clear,
|
||||
input::-ms-reveal {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* css minifier must not combine these.
|
||||
* style will not apply otherwise */
|
||||
input::-ms-input-placeholder {
|
||||
color: #ccd;
|
||||
}
|
||||
|
||||
input::placeholder {
|
||||
color: #ccc;
|
||||
}
|
||||
|
||||
@@ -148,8 +148,7 @@ function loadTimeZones() {
|
||||
|
||||
}
|
||||
|
||||
function validateForm(form) {
|
||||
|
||||
function validatePassword(password) {
|
||||
// http://www.the-art-of-web.com/javascript/validate-password/
|
||||
// at least one lowercase and one uppercase letter or number
|
||||
// at least eight characters (letters, numbers or special characters)
|
||||
@@ -157,21 +156,45 @@ function validateForm(form) {
|
||||
// MUST be 8..63 printable ASCII characters. See:
|
||||
// https://en.wikipedia.org/wiki/Wi-Fi_Protected_Access#Target_users_(authentication_key_distribution)
|
||||
// https://github.com/xoseperez/espurna/issues/1151
|
||||
var re_password = /^(?=.*[A-Z\d])(?=.*[a-z])[\w~!@#$%^&*\(\)<>,.\?;:{}\[\]\\|]{8,63}$/;
|
||||
|
||||
// password
|
||||
var adminPass1 = $("input[name='adminPass']", form).first().val();
|
||||
if (adminPass1.length > 0 && !re_password.test(adminPass1)) {
|
||||
alert("The password you have entered is not valid, it must be 8..63 characters and have at least 1 lowercase and 1 uppercase / number!");
|
||||
return false;
|
||||
var re_password = /^(?=.*[A-Z\d])(?=.*[a-z])[\w~!@#$%^&*\(\)<>,.\?;:{}\[\]\\|]{8,63}$/;
|
||||
return (
|
||||
(password !== undefined)
|
||||
&& (typeof password === "string")
|
||||
&& (password.length > 0)
|
||||
&& re_password.test(password)
|
||||
);
|
||||
}
|
||||
|
||||
function validateFormPasswords(form) {
|
||||
var passwords = $("input[name='adminPass1'],input[name='adminPass2']", form);
|
||||
var adminPass1 = passwords.first().val(),
|
||||
adminPass2 = passwords.last().val();
|
||||
|
||||
var formValidity = passwords.first()[0].checkValidity();
|
||||
if (formValidity && (adminPass1.length === 0) && (adminPass2.length === 0)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
var validPass1 = validatePassword(adminPass1),
|
||||
validPass2 = validatePassword(adminPass2);
|
||||
|
||||
if (formValidity && validPass1 && validPass2) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!formValidity || (adminPass1.length > 0 && !validPass1)) {
|
||||
alert("The password you have entered is not valid, it must be 8..63 characters and have at least 1 lowercase and 1 uppercase / number!");
|
||||
}
|
||||
|
||||
var adminPass2 = $("input[name='adminPass']", form).last().val();
|
||||
if (adminPass1 !== adminPass2) {
|
||||
alert("Passwords are different!");
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function validateFormHostname(form) {
|
||||
// RFCs mandate that a hostname's labels may contain only
|
||||
// the ASCII letters 'a' through 'z' (case-insensitive),
|
||||
// the digits '0' through '9', and the hyphen.
|
||||
@@ -184,18 +207,21 @@ function validateForm(form) {
|
||||
var re_hostname = new RegExp('^(?!-)[A-Za-z0-9-]{0,30}[A-Za-z0-9]$');
|
||||
|
||||
var hostname = $("input[name='hostname']", form);
|
||||
var hasChanged = ("true" === hostname.attr("hasChanged"));
|
||||
if (!hasChanged) {
|
||||
if ("true" !== hostname.attr("hasChanged")) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!re_hostname.test(hostname.val())) {
|
||||
alert("Hostname cannot be empty and may only contain the ASCII letters ('A' through 'Z' and 'a' through 'z'), the digits '0' through '9', and the hyphen ('-')! They can neither start or end with an hyphen.");
|
||||
return false;
|
||||
if (re_hostname.test(hostname.val())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return true;
|
||||
alert("Hostname cannot be empty and may only contain the ASCII letters ('A' through 'Z' and 'a' through 'z'), the digits '0' through '9', and the hyphen ('-')! They can neither start or end with an hyphen.");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function validateForm(form) {
|
||||
return validateFormPasswords(form) && validateFormHostname(form);
|
||||
}
|
||||
|
||||
function getValue(element) {
|
||||
@@ -227,6 +253,12 @@ function addValue(data, name, value) {
|
||||
"node", "key", "topic"
|
||||
];
|
||||
|
||||
|
||||
// join both adminPass 1 and 2
|
||||
if (name.startsWith("adminPass")) {
|
||||
name = "adminPass";
|
||||
}
|
||||
|
||||
if (name in data) {
|
||||
if (!Array.isArray(data[name])) {
|
||||
data[name] = [data[name]];
|
||||
@@ -262,26 +294,67 @@ function getData(form) {
|
||||
|
||||
}
|
||||
|
||||
function randomString(length, chars) {
|
||||
var mask = "";
|
||||
if (chars.indexOf("a") > -1) { mask += "abcdefghijklmnopqrstuvwxyz"; }
|
||||
if (chars.indexOf("A") > -1) { mask += "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; }
|
||||
if (chars.indexOf("#") > -1) { mask += "0123456789"; }
|
||||
if (chars.indexOf("@") > -1) { mask += "ABCDEF"; }
|
||||
if (chars.indexOf("!") > -1) { mask += "~`!@#$%^&*()_+-={}[]:\";'<>?,./|\\"; }
|
||||
var result = "";
|
||||
for (var i = length; i > 0; --i) {
|
||||
result += mask[Math.round(Math.random() * (mask.length - 1))];
|
||||
function randomString(length, args) {
|
||||
if (typeof args === "undefined") {
|
||||
args = {
|
||||
lowercase: true,
|
||||
uppercase: true,
|
||||
numbers: true,
|
||||
special: true
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
||||
var mask = "";
|
||||
if (args.lowercase) { mask += "abcdefghijklmnopqrstuvwxyz"; }
|
||||
if (args.uppercase) { mask += "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; }
|
||||
if (args.numbers || args.hex) { mask += "0123456789"; }
|
||||
if (args.hex) { mask += "ABCDEF"; }
|
||||
if (args.special) { mask += "~`!@#$%^&*()_+-={}[]:\";'<>?,./|\\"; }
|
||||
|
||||
var source = new Uint32Array(length);
|
||||
var result = new Array(length);
|
||||
|
||||
window.crypto.getRandomValues(source).forEach(function(value, i) {
|
||||
result[i] = mask[value % mask.length];
|
||||
});
|
||||
|
||||
return result.join("");
|
||||
}
|
||||
|
||||
function generateAPIKey() {
|
||||
var apikey = randomString(16, "@#");
|
||||
var apikey = randomString(16, {hex: true});
|
||||
$("input[name='apiKey']").val(apikey);
|
||||
return false;
|
||||
}
|
||||
|
||||
function generatePassword() {
|
||||
var password = "";
|
||||
do {
|
||||
password = randomString(10);
|
||||
} while (!validatePassword(password));
|
||||
|
||||
return password;
|
||||
}
|
||||
|
||||
function toggleVisiblePassword() {
|
||||
var elem = this.previousElementSibling;
|
||||
if (elem.type === "password") {
|
||||
elem.type = "text";
|
||||
} else {
|
||||
elem.type = "password";
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function doGeneratePassword() {
|
||||
$("input", $("#formPassword"))
|
||||
.val(generatePassword())
|
||||
.each(function() {
|
||||
this.type = "text";
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
function getJson(str) {
|
||||
try {
|
||||
return JSON.parse(str);
|
||||
@@ -305,7 +378,7 @@ function sendConfig(data) {
|
||||
function setOriginalsFromValues(force) {
|
||||
var force = (true === force);
|
||||
$("input,select").each(function() {
|
||||
var initial = (null === $(this).attr("original"));
|
||||
var initial = (undefined === $(this).attr("original"));
|
||||
if (force || initial) {
|
||||
$(this).attr("original", $(this).val());
|
||||
}
|
||||
@@ -424,7 +497,7 @@ function doUpgrade() {
|
||||
|
||||
function doUpdatePassword() {
|
||||
var form = $("#formPassword");
|
||||
if (validateForm(form)) {
|
||||
if (validateFormPasswords(form)) {
|
||||
sendConfig(getData(form));
|
||||
}
|
||||
return false;
|
||||
@@ -478,11 +551,11 @@ function doReconnect(ask) {
|
||||
|
||||
function doUpdate() {
|
||||
|
||||
var form = $("#formSave");
|
||||
if (validateForm(form)) {
|
||||
var forms = $(".form-settings");
|
||||
if (validateForm(forms)) {
|
||||
|
||||
// Get data
|
||||
sendConfig(getData(form));
|
||||
sendConfig(getData(forms));
|
||||
|
||||
// Empty special fields
|
||||
$(".pwrExpected").val(0);
|
||||
@@ -756,6 +829,7 @@ function addNetwork() {
|
||||
$(this).attr("tabindex", tabindex);
|
||||
tabindex++;
|
||||
});
|
||||
$(".password-reveal", line).on("click", toggleVisiblePassword);
|
||||
$(line).find(".button-del-network").on("click", delNetwork);
|
||||
$(line).find(".button-more-network").on("click", moreNetwork);
|
||||
line.appendTo("#networks");
|
||||
@@ -1578,12 +1652,15 @@ $(function() {
|
||||
createCheckboxes();
|
||||
setInterval(function() { keepTime(); }, 1000);
|
||||
|
||||
$(".password-reveal").on("click", toggleVisiblePassword);
|
||||
|
||||
$("#menuLink").on("click", toggleMenu);
|
||||
$(".pure-menu-link").on("click", showPanel);
|
||||
$("progress").attr({ value: 0, max: 100 });
|
||||
|
||||
$(".button-update").on("click", doUpdate);
|
||||
$(".button-update-password").on("click", doUpdatePassword);
|
||||
$(".button-generate-password").on("click", doGeneratePassword);
|
||||
$(".button-reboot").on("click", doReboot);
|
||||
$(".button-reconnect").on("click", doReconnect);
|
||||
$(".button-wifi-scan").on("click", doScan);
|
||||
|
||||
@@ -28,40 +28,45 @@
|
||||
|
||||
<div class="content">
|
||||
|
||||
<form id="formPassword" class="pure-form" action="/" method="post">
|
||||
<form id="formPassword" class="pure-form" autocomplete="off">
|
||||
|
||||
<div class="panel block">
|
||||
<div class="panel block" id="panel-password">
|
||||
|
||||
<div class="header">
|
||||
<h1>SECURITY</h1>
|
||||
<h2>Before using this device you have to change the default password for the user 'admin'. This password will be used for the <strong>AP mode hotspot</strong>, the <strong>web interface</strong> (where you are now) and the <strong>over-the-air updates</strong>.</h2>
|
||||
<h2>Before using this device you have to change the default password for the user <strong>admin</strong>. This password will be used for the <strong>AP mode hotspot</strong>, the <strong>web interface</strong> (where you are now) and the <strong>over-the-air updates</strong>.</h2>
|
||||
</div>
|
||||
|
||||
<div class="page">
|
||||
|
||||
<fieldset>
|
||||
|
||||
<div class="pure-g">
|
||||
<label class="pure-u-1 pure-u-lg-1-4">Admin password</label>
|
||||
<input name="adminPass" class="pure-u-1 pure-u-lg-3-4" maxlength="63" type="password" tabindex="1" autocomplete="false" />
|
||||
<div class="pure-u-0 pure-u-lg-1-4"></div>
|
||||
<div class="pure-u-1 pure-u-lg-3-4 hint">
|
||||
The administrator password is used to access this web interface (user 'admin'), but also to connect to the device when in AP mode or to flash a new firmware over-the-air (OTA).<br />
|
||||
It must be <strong>8..63 characters</strong> (numbers and letters and any of these special characters: _,.;:~!?@#$%^&*<>\|(){}[]) and have at least <strong>one lowercase</strong> and <strong>one uppercase</strong> or <strong>one number</strong>.</div>
|
||||
<label class="pure-u-1 pure-u-lg-1-4" for="adminPass1">New Password</label>
|
||||
<input class="pure-u-1 pure-u-lg-3-4" name="adminPass1" minlength="8" maxlength="63" type="password" tabindex="1" autocomplete="false" spellcheck="false" required />
|
||||
<span class="no-select password-reveal"></span>
|
||||
</div>
|
||||
|
||||
<div class="pure-g">
|
||||
<label class="pure-u-1 pure-u-lg-1-4">Repeat password</label>
|
||||
<input name="adminPass" class="pure-u-1 pure-u-lg-3-4" type="password" tabindex="2" autocomplete="false" />
|
||||
<label class="pure-u-1 pure-u-lg-1-4" for="adminPass2">Repeat password</label>
|
||||
<input class="pure-u-1 pure-u-lg-3-4" name="adminPass2" minlength="8" maxlength="63" type="password" tabindex="2" autocomplete="false" spellcheck="false" required />
|
||||
<span class="no-select password-reveal"></span>
|
||||
</div>
|
||||
|
||||
<div class="pure-u-0 pure-u-lg-1-4 more"></div>
|
||||
<button class="pure-button button-update-password" type="button">Update</button>
|
||||
|
||||
</fieldset>
|
||||
|
||||
<div class="pure-g">
|
||||
<div class="pure-u-1 pure-u-lg-1 hint">
|
||||
Password must be <strong>8..63 characters</strong> (numbers and letters and any of these special characters: _,.;:~!?@#$%^&*<>\|(){}[]) and have at least <strong>one lowercase</strong> and <strong>one uppercase</strong> or <strong>one number</strong>.</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="pure-g">
|
||||
<button class="pure-u-11-24 pure-u-lg-1-4 pure-button button-generate-password" type="button" title="Generate password based on password policy">Generate</button>
|
||||
<div class="pure-u-2-24 pure-u-lg-1-2"></div>
|
||||
<button class="pure-u-11-24 pure-u-lg-1-4 pure-button button-update-password" type="button" title="Save new password">Save</button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
|
||||
</div> <!-- content -->
|
||||
@@ -309,8 +314,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<form id="formSave" class="pure-form" action="/" method="post" enctype="multipart/form-data">
|
||||
|
||||
<form id="form-general" class="pure-form form-settings">
|
||||
<div class="panel" id="panel-general">
|
||||
|
||||
<div class="header">
|
||||
@@ -382,7 +386,9 @@
|
||||
</fieldset>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<form id="form-relay" class="pure-form form-settings">
|
||||
<div class="panel" id="panel-relay">
|
||||
|
||||
<div class="header">
|
||||
@@ -414,8 +420,10 @@
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<!-- removeIf(!light) -->
|
||||
<!-- removeIf(!light) -->
|
||||
<form id="form-color" class="pure-form form-settings">
|
||||
<div class="panel" id="panel-color">
|
||||
|
||||
<div class="header">
|
||||
@@ -501,8 +509,10 @@
|
||||
</fieldset>
|
||||
</div>
|
||||
</div>
|
||||
<!-- endRemoveIf(!light) -->
|
||||
</form>
|
||||
<!-- endRemoveIf(!light) -->
|
||||
|
||||
<form id="form-admin" class="pure-form form-settings">
|
||||
<div class="panel" id="panel-admin">
|
||||
|
||||
<div class="header">
|
||||
@@ -516,25 +526,25 @@
|
||||
|
||||
<div class="pure-g">
|
||||
<label class="pure-u-1 pure-u-lg-1-4">Settings</label>
|
||||
<div class="pure-u-1-3 pure-u-lg-1-4"><button class="pure-button button-settings-backup pure-u-23-24">Backup</button></div>
|
||||
<div class="pure-u-1-3 pure-u-lg-1-4"><button class="pure-button button-settings-restore pure-u-23-24">Restore</button></div>
|
||||
<div class="pure-u-1-3 pure-u-lg-1-4"><button class="pure-button button-settings-factory pure-u-1">Factory Reset</button></div>
|
||||
<div class="pure-u-1-3 pure-u-lg-1-4"><button type="button" class="pure-button button-settings-backup pure-u-23-24">Backup</button></div>
|
||||
<div class="pure-u-1-3 pure-u-lg-1-4"><button type="button" class="pure-button button-settings-restore pure-u-23-24">Restore</button></div>
|
||||
<div class="pure-u-1-3 pure-u-lg-1-4"><button type="button" class="pure-button button-settings-factory pure-u-1">Factory Reset</button></div>
|
||||
</div>
|
||||
|
||||
<div class="pure-g">
|
||||
<label class="pure-u-1 pure-u-lg-1-4">Admin password</label>
|
||||
<input name="adminPass" class="pure-u-1 pure-u-lg-3-4" maxlength="63" type="password" action="reboot" tabindex="11" autocomplete="false" />
|
||||
<input name="adminPass1" class="pure-u-1 pure-u-lg-3-4" placeholder="New password" minlength="8" maxlength="63" type="password" action="reboot" tabindex="11" autocomplete="false" spellcheck="false" />
|
||||
<span class="no-select password-reveal"></span>
|
||||
<div class="pure-u-1 pure-u-lg-1-4"></div>
|
||||
<input name="adminPass2" class="pure-u-1 pure-u-lg-3-4" placeholder="Repeat password" minlength="8" maxlength="63" type="password" action="reboot" tabindex="12" autocomplete="false" spellcheck="false" />
|
||||
<span class="no-select password-reveal"></span>
|
||||
|
||||
<div class="pure-u-0 pure-u-lg-1-4"></div>
|
||||
<div class="pure-u-1 pure-u-lg-3-4 hint">
|
||||
The administrator password is used to access this web interface (user 'admin'), but also to connect to the device when in AP mode or to flash a new firmware over-the-air (OTA).<br />
|
||||
It must be <strong>8..63 characters</strong> (numbers and letters and any of these special characters: _,.;:~!?@#$%^&*<>\|(){}[]) and have at least <strong>one lowercase</strong> and <strong>one uppercase</strong> or <strong>one number</strong>.</div>
|
||||
</div>
|
||||
|
||||
<div class="pure-g">
|
||||
<label class="pure-u-1 pure-u-lg-1-4">Repeat password</label>
|
||||
<input name="adminPass" class="pure-u-1 pure-u-lg-3-4" maxlength="63" type="password" action="reboot" tabindex="12" autocomplete="false" />
|
||||
</div>
|
||||
|
||||
<div class="pure-g">
|
||||
<label class="pure-u-1 pure-u-lg-1-4">HTTP port</label>
|
||||
<input name="webPort" class="pure-u-1 pure-u-lg-1-4" type="text" action="reboot" tabindex="13" />
|
||||
@@ -556,6 +566,17 @@
|
||||
<div class="pure-u-1 pure-u-lg-1-4"><input type="checkbox" name="apiEnabled" /></div>
|
||||
</div>
|
||||
|
||||
<div class="pure-g module module-api">
|
||||
<label class="pure-u-1 pure-u-lg-1-4">Restful API</label>
|
||||
<div class="pure-u-1 pure-u-lg-1-4"><input type="checkbox" name="apiRestFul" /></div>
|
||||
<div class="pure-u-0 pure-u-lg-1-2"></div>
|
||||
<div class="pure-u-0 pure-u-lg-1-4"></div>
|
||||
<div class="pure-u-1 pure-u-lg-3-4 hint">
|
||||
If enabled, API requests to change a status (like a relay) must be done using PUT.
|
||||
If disabled you can issue them as GET requests (easier from a browser).
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="pure-g module module-api">
|
||||
<label class="pure-u-1 pure-u-lg-1-4">Real time API</label>
|
||||
<div class="pure-u-1 pure-u-lg-1-4"><input type="checkbox" name="apiRealTime" /></div>
|
||||
@@ -570,7 +591,7 @@
|
||||
<div class="pure-g module module-api">
|
||||
<label class="pure-u-1 pure-u-lg-1-4">HTTP API Key</label>
|
||||
<input name="apiKey" class="pure-u-3-4 pure-u-lg-1-2" type="text" tabindex="14" />
|
||||
<div class=" pure-u-1-4 pure-u-lg-1-4"><button class="pure-button button-apikey pure-u-23-24">Auto</button></div>
|
||||
<div class="pure-u-1-4 pure-u-lg-1-4"><button type="button" class="pure-button button-apikey pure-u-23-24">Auto</button></div>
|
||||
<div class="pure-u-0 pure-u-lg-1-4"></div>
|
||||
<div class="pure-u-1 pure-u-lg-3-4 hint">
|
||||
This is the key you will have to pass with every HTTP request to the API, either to get or write values.
|
||||
@@ -603,8 +624,8 @@
|
||||
<div class="pure-g">
|
||||
<label class="pure-u-1 pure-u-lg-1-4">Upgrade</label>
|
||||
<input class="pure-u-1-2 pure-u-lg-1-2" name="filename" type="text" readonly />
|
||||
<div class=" pure-u-1-4 pure-u-lg-1-8"><button class="pure-button button-upgrade-browse pure-u-23-24">Browse</button></div>
|
||||
<div class=" pure-u-1-4 pure-u-lg-1-8"><button class="pure-button button-upgrade pure-u-23-24">Upgrade</button></div>
|
||||
<div class="pure-u-1-4 pure-u-lg-1-8"><button type="button" class="pure-button button-upgrade-browse pure-u-23-24">Browse</button></div>
|
||||
<div class="pure-u-1-4 pure-u-lg-1-8"><button type="button" class="pure-button button-upgrade pure-u-23-24">Upgrade</button></div>
|
||||
<div class="pure-u-0 pure-u-lg-1-4"></div>
|
||||
<div class="pure-u-1 pure-u-lg-3-4 hint">The device has <span name="free_size"></span> bytes available for OTA updates. If your image is larger than this consider doing a <a href="https://github.com/xoseperez/espurna/wiki/TwoStepUpdates" target="_blank"><strong>two-step update</strong></a>.</div>
|
||||
<div class="pure-u-0 pure-u-lg-1-4"></div>
|
||||
@@ -615,7 +636,9 @@
|
||||
</fieldset>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<form id="form-wifi" class="pure-form form-settings">
|
||||
<div class="panel" id="panel-wifi">
|
||||
|
||||
<div class="header">
|
||||
@@ -657,7 +680,9 @@
|
||||
</fieldset>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<form id="form-schedule" class="pure-form form-settings">
|
||||
<div class="panel" id="panel-schedule">
|
||||
|
||||
<div class="header">
|
||||
@@ -681,8 +706,10 @@
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<!-- removeIf(!rfm69) -->
|
||||
<!-- removeIf(!rfm69) -->
|
||||
<form id="form-mapping" class="pure-form form-settings">
|
||||
<div class="panel" id="panel-mapping">
|
||||
|
||||
<div class="header">
|
||||
@@ -711,10 +738,12 @@
|
||||
|
||||
</fieldset>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<form id="form-messages" class="pure-form">
|
||||
<div class="panel" id="panel-messages">
|
||||
|
||||
<div class="header">
|
||||
<h1>MESSAGES</h1>
|
||||
<h2>
|
||||
@@ -746,15 +775,17 @@
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<button class="pure-button button-clear-filters">Clear filters</button>
|
||||
<button class="pure-button button-clear-messages">Clear messages</button>
|
||||
<button class="pure-button button-clear-counts">Clear counts</button>
|
||||
<button type="button" class="pure-button button-clear-filters">Clear filters</button>
|
||||
<button type="button" class="pure-button button-clear-messages">Clear messages</button>
|
||||
<button type="button" class="pure-button button-clear-counts">Clear counts</button>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<!-- endRemoveIf(!rfm69) -->
|
||||
</form>
|
||||
<!-- endRemoveIf(!rfm69) -->
|
||||
|
||||
<form id="form-mqtt" class="pure-form form-settings">
|
||||
<div class="panel" id="panel-mqtt">
|
||||
|
||||
<div class="header">
|
||||
@@ -783,12 +814,13 @@
|
||||
|
||||
<div class="pure-g">
|
||||
<label class="pure-u-1 pure-u-lg-1-4">MQTT User</label>
|
||||
<input class="pure-u-1 pure-u-lg-1-4" name="mqttUser" type="text" tabindex="23" placeholder="Leave blank if no user" autocomplete="false" />
|
||||
<input class="pure-u-1 pure-u-lg-1-4" name="mqttUser" type="text" tabindex="23" placeholder="Leave blank if no user" autocomplete="off" />
|
||||
</div>
|
||||
|
||||
<div class="pure-g">
|
||||
<label class="pure-u-1 pure-u-lg-1-4">MQTT Password</label>
|
||||
<input class="pure-u-1 pure-u-lg-1-4" name="mqttPassword" type="password" tabindex="24" placeholder="Leave blank if no pass" autocomplete="false" />
|
||||
<input class="pure-u-1 pure-u-lg-1-4" name="mqttPassword" type="password" tabindex="24" placeholder="Leave blank if no pass" autocomplete="new-password" spellcheck="false" />
|
||||
<span class="no-select password-reveal"></span>
|
||||
</div>
|
||||
|
||||
<div class="pure-g">
|
||||
@@ -873,7 +905,9 @@
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<form id="form-ntp" class="pure-form form-settings">
|
||||
<div class="panel" id="panel-ntp">
|
||||
|
||||
<div class="header">
|
||||
@@ -917,7 +951,9 @@
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<form id="form-domoticz" class="pure-form form-settings">
|
||||
<div class="panel" id="panel-domoticz">
|
||||
|
||||
<div class="header">
|
||||
@@ -964,7 +1000,9 @@
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<form id="form-ha" class="pure-form form-settings">
|
||||
<div class="panel" id="panel-ha">
|
||||
|
||||
<div class="header">
|
||||
@@ -1001,7 +1039,7 @@
|
||||
|
||||
<div class="pure-g">
|
||||
<label class="pure-u-1 pure-u-lg-1-4">Configuration</label>
|
||||
<div class="pure-u-1-4 pure-u-lg-3-4"><button class="pure-button button-ha-config pure-u-1-3">Show</button></div>
|
||||
<div class="pure-u-1-4 pure-u-lg-3-4"><button type="button" class="pure-button button-ha-config pure-u-1-3">Show</button></div>
|
||||
<div class="pure-u-0 pure-u-lg-1-4"></div>
|
||||
<div class="pure-u-1 pure-u-lg-3-4 hint">
|
||||
These are the settings you should copy to your Home Assistant "configuration.yaml" file.
|
||||
@@ -1018,7 +1056,9 @@
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<form id="form-thingspeak" class="pure-form form-settings">
|
||||
<div class="panel" id="panel-thingspeak">
|
||||
|
||||
<div class="header">
|
||||
@@ -1060,7 +1100,9 @@
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<form id="form-idb" class="pure-form form-settings">
|
||||
<div class="panel" id="panel-idb">
|
||||
|
||||
<div class="header">
|
||||
@@ -1096,19 +1138,22 @@
|
||||
|
||||
<div class="pure-g">
|
||||
<label class="pure-u-1 pure-u-lg-1-4">Username</label>
|
||||
<input class="pure-u-1 pure-u-lg-3-4" name="idbUsername" type="text" tabindex="44" autocomplete="false" />
|
||||
<input class="pure-u-1 pure-u-lg-3-4" name="idbUsername" type="text" tabindex="44" autocomplete="off" />
|
||||
</div>
|
||||
|
||||
<div class="pure-g">
|
||||
<label class="pure-u-1 pure-u-lg-1-4">Password</label>
|
||||
<input class="pure-u-1 pure-u-lg-3-4" name="idbPassword" type="password" tabindex="45" autocomplete="false" />
|
||||
<input class="pure-u-1 pure-u-lg-3-4" name="idbPassword" type="password" tabindex="45" autocomplete="new-password" spellcheck="false" />
|
||||
<span class="no-select password-reveal"></span>
|
||||
</div>
|
||||
|
||||
</fieldset>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<form id="form-dbg" class="pure-form">
|
||||
<div class="panel" id="panel-dbg">
|
||||
|
||||
<div class="header">
|
||||
@@ -1127,12 +1172,12 @@
|
||||
Write a command and click send to execute it on the device. The output will be shown in the debug text area below.
|
||||
</div>
|
||||
<input name="dbgcmd" class="pure-u-3-4" type="text" tabindex="2" />
|
||||
<div class=" pure-u-1-4 pure-u-lg-1-4"><button class="pure-button button-dbgcmd pure-u-23-24">Send</button></div>
|
||||
<div class="pure-u-1-4 pure-u-lg-1-4"><button type="button" class="pure-button button-dbgcmd pure-u-23-24">Send</button></div>
|
||||
</div>
|
||||
|
||||
<div class="pure-g">
|
||||
<textarea class="pure-u-1 terminal" id="weblog" name="weblog" wrap="off" readonly></textarea>
|
||||
<div class=" pure-u-1-4 pure-u-lg-1-4"><button class="pure-button button-dbg-clear pure-u-23-24">Clear</button></div>
|
||||
<div class="pure-u-1-4 pure-u-lg-1-4"><button type="button" class="pure-button button-dbg-clear pure-u-23-24">Clear</button></div>
|
||||
</div>
|
||||
|
||||
</fieldset>
|
||||
@@ -1140,8 +1185,10 @@
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<!-- removeIf(!sensor) -->
|
||||
<!-- removeIf(!sensor) -->
|
||||
<form id="form-sns" class="pure-form form-settings">
|
||||
<div class="panel" id="panel-sns">
|
||||
|
||||
<div class="header">
|
||||
@@ -1305,9 +1352,11 @@
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!-- endRemoveIf(!sensor) -->
|
||||
</form>
|
||||
<!-- endRemoveIf(!sensor) -->
|
||||
|
||||
<!-- removeIf(!rfbridge) -->
|
||||
<!-- removeIf(!rfbridge) -->
|
||||
<form id="form-rfb" class="pure-form form-settings">
|
||||
<div class="panel" id="panel-rfb">
|
||||
|
||||
<div class="header">
|
||||
@@ -1327,10 +1376,10 @@
|
||||
<div id="rfbNodes"></div>
|
||||
</fieldset>
|
||||
</div>
|
||||
</div>
|
||||
<!-- endRemoveIf(!rfbridge) -->
|
||||
|
||||
</div>
|
||||
</form>
|
||||
<!-- endRemoveIf(!rfbridge) -->
|
||||
|
||||
</div> <!-- content -->
|
||||
|
||||
@@ -1371,7 +1420,8 @@
|
||||
<div class="pure-u-1-6 pure-u-lg-1-12"><button type="button" class="pure-button button-more-network pure-u-1">...</button></div>
|
||||
|
||||
<label class="pure-u-1 pure-u-lg-1-4 more">Password</label>
|
||||
<input class="pure-u-1 pure-u-lg-3-4 more" name="pass" type="password" action="reconnect" value="" tabindex="0" autocomplete="false" />
|
||||
<input class="pure-u-1 pure-u-lg-3-4 more" name="pass" type="password" action="reconnect" value="" tabindex="0" autocomplete="new-password" spellcheck="false" />
|
||||
<span class="no-select password-reveal more"></span>
|
||||
|
||||
<label class="pure-u-1 pure-u-lg-1-4 more">Static IP</label>
|
||||
<input class="pure-u-1 pure-u-lg-3-4 more" name="ip" type="text" action="reconnect" value="" maxlength="15" tabindex="0" autocomplete="false" />
|
||||
@@ -1594,7 +1644,7 @@
|
||||
<!-- removeIf(!rfm69) -->
|
||||
<div id="nodeTemplate" class="template">
|
||||
<div class="pure-g">
|
||||
<div class="pure-u-md-1-6 pure-u-1-2"><input name="node" type="text" class="pure-u-11-12" value="" size="8" tabindex="0" placeholder="Node ID"></div>
|
||||
<div class="pure-u-md-1-6 pure-u-1-2"><input name="node" type="text" class="pure-u-11-12" value="" size="8" tabindex="0" placeholder="Node ID" autocomplete="false"></div>
|
||||
<div class="pure-u-md-1-6 pure-u-1-2"><input name="key" type="text" class="pure-u-11-12" value="" size="8" tabindex="0" placeholder="Key"></div>
|
||||
<div class="pure-u-md-1-2 pure-u-3-4"><input name="topic" type="text" class="pure-md-11-12 pure-u-23-24" value="" size="8" tabindex="0" placeholder="MQTT Topic"></div>
|
||||
<div class="pure-u-md-1-6 pure-u-1-4"><button type="button" class="pure-button button-del-mapping pure-u-5-6 pure-u-md-5-6">Del</button></div>
|
||||
|
||||
BIN
code/html/vendor/images/sort_asc_disabled.png
vendored
Normal file
BIN
code/html/vendor/images/sort_asc_disabled.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 148 B |
BIN
code/html/vendor/images/sort_desc_disabled.png
vendored
Normal file
BIN
code/html/vendor/images/sort_desc_disabled.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 146 B |
Reference in New Issue
Block a user