14
.github/workflows/beta.yml
vendored
14
.github/workflows/beta.yml
vendored
@@ -13,7 +13,7 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
board: [esp32, esp32-s3, esp32-s3-oct, esp32-c3, esp32-c6, esp32-h2, esp32-solo1]
|
||||
build: [release, debug]
|
||||
build: [release]
|
||||
env:
|
||||
BOARD: ${{ matrix.board }}
|
||||
VARIANT: ${{ matrix.name || matrix.board }}
|
||||
@@ -107,24 +107,16 @@ jobs:
|
||||
with:
|
||||
path: release
|
||||
pattern: '*-release-assets'
|
||||
- name: Download debug assets
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
path: debug
|
||||
pattern: '*-debug-assets'
|
||||
- name: Copy binaries to ota/beta
|
||||
env:
|
||||
Version: ${{ github.run_id }}.${{ github.run_number }}.${{ github.run_attempt }}
|
||||
run: |
|
||||
mkdir -p ota/beta/
|
||||
mkdir -p ota/debug/beta/
|
||||
mkdir -p ota/master/
|
||||
mkdir -p ota/debug/master/
|
||||
mkdir -p webflash/
|
||||
mkdir -p resources/
|
||||
mkdir -p src/
|
||||
cp -vf release/*/nuki_hub_*.bin ota/beta/
|
||||
cp -vf debug/*/nuki_hub_*.bin ota/debug/beta/
|
||||
cp -vf master/resources/ota_manifest.py resources/ota_manifest.py
|
||||
cp -vf master/src/Config.h src/Config.h
|
||||
python3 resources/ota_manifest.py beta $Version
|
||||
@@ -132,14 +124,12 @@ jobs:
|
||||
rm -rf .github .gitignore .gitmodules
|
||||
touch ota/beta/empty
|
||||
touch ota/master/empty
|
||||
touch ota/debug/beta/empty
|
||||
touch ota/debug/master/empty
|
||||
touch webflash/empty
|
||||
- name: Commit binaries to binary
|
||||
uses: stefanzweifel/git-auto-commit-action@v5
|
||||
with:
|
||||
commit_message: "Update binaries"
|
||||
file_pattern: 'ota/* ota/debug/* ota/master/* ota/debug/master/* ota/beta/* ota/debug/beta/* webflash/*'
|
||||
file_pattern: 'ota/* ota/master/* ota/beta/* webflash/*'
|
||||
branch: binary
|
||||
skip_dirty_check: true
|
||||
skip_fetch: true
|
||||
|
||||
2
.github/workflows/build.yml
vendored
2
.github/workflows/build.yml
vendored
@@ -19,7 +19,7 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
board: [esp32, esp32-s3, esp32-s3-oct, esp32-c3, esp32-c6, esp32-h2, esp32-solo1]
|
||||
build: [release, debug]
|
||||
build: [release]
|
||||
env:
|
||||
BOARD: ${{ matrix.board }}
|
||||
VARIANT: ${{ matrix.name || matrix.board }}
|
||||
|
||||
13
.github/workflows/nightly.yml
vendored
13
.github/workflows/nightly.yml
vendored
@@ -35,7 +35,7 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
board: [esp32, esp32-s3, esp32-s3-oct, esp32-c3, esp32-c6, esp32-h2, esp32-solo1]
|
||||
build: [release, debug]
|
||||
build: [release]
|
||||
env:
|
||||
BOARD: ${{ matrix.board }}
|
||||
VARIANT: ${{ matrix.name || matrix.board }}
|
||||
@@ -130,19 +130,12 @@ jobs:
|
||||
with:
|
||||
path: release
|
||||
pattern: '*-release-assets'
|
||||
- name: Download debug assets
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
path: debug
|
||||
pattern: '*-debug-assets'
|
||||
- name: Copy binaries to ota/master
|
||||
env:
|
||||
Version: ${{ github.run_id }}.${{ github.run_number }}.${{ github.run_attempt }}
|
||||
run: |
|
||||
mkdir -p ota/beta/
|
||||
mkdir -p ota/debug/beta/
|
||||
mkdir -p ota/master/
|
||||
mkdir -p ota/debug/master/
|
||||
mkdir -p webflash/
|
||||
mkdir -p resources/
|
||||
mkdir -p src/
|
||||
@@ -155,14 +148,12 @@ jobs:
|
||||
rm -rf .github .gitignore .gitmodules
|
||||
touch ota/beta/empty
|
||||
touch ota/master/empty
|
||||
touch ota/debug/beta/empty
|
||||
touch ota/debug/master/empty
|
||||
touch webflash/empty
|
||||
- name: Commit binaries to binary
|
||||
uses: stefanzweifel/git-auto-commit-action@v5
|
||||
with:
|
||||
commit_message: "Update binaries"
|
||||
file_pattern: 'ota/* ota/debug/* ota/master/* ota/debug/master/* ota/beta/* ota/debug/beta/* webflash/*'
|
||||
file_pattern: 'ota/* ota/master/* ota/beta/* webflash/*'
|
||||
branch: binary
|
||||
skip_dirty_check: true
|
||||
skip_fetch: true
|
||||
|
||||
15
.github/workflows/release.yml
vendored
15
.github/workflows/release.yml
vendored
@@ -13,7 +13,7 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
board: [esp32, esp32-s3, esp32-s3-oct, esp32-c3, esp32-c6, esp32-h2, esp32-solo1]
|
||||
build: [release, debug]
|
||||
build: [release]
|
||||
env:
|
||||
BOARD: ${{ matrix.board }}
|
||||
VARIANT: ${{ matrix.name || matrix.board }}
|
||||
@@ -109,11 +109,6 @@ jobs:
|
||||
with:
|
||||
path: release
|
||||
pattern: '*-release-assets'
|
||||
- name: Download debug assets
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
path: debug
|
||||
pattern: '*-debug-assets'
|
||||
- name: Build zip archives
|
||||
id: zip
|
||||
env:
|
||||
@@ -171,14 +166,11 @@ jobs:
|
||||
Version: ${{ github.run_id }}.${{ github.run_number }}.${{ github.run_attempt }}
|
||||
run: |
|
||||
mkdir -p ota/beta/
|
||||
mkdir -p ota/debug/beta/
|
||||
mkdir -p ota/master/
|
||||
mkdir -p ota/debug/master/
|
||||
mkdir -p webflash/
|
||||
mkdir -p resources/
|
||||
mkdir -p src/
|
||||
cp -vf release/*/nuki_hub_*.bin ota/
|
||||
cp -vf debug/*/nuki_hub_*.bin ota/debug/
|
||||
cp -vf release/*/webflash_nuki_hub_*.bin webflash/
|
||||
cp -vf master/resources/ota_manifest.py resources/ota_manifest.py
|
||||
cp -vf master/src/Config.h src/Config.h
|
||||
@@ -186,18 +178,15 @@ jobs:
|
||||
python3 resources/ota_manifest.py beta none
|
||||
find * -not -path "ota*" -not -path "webflash*" -delete
|
||||
rm -rf ota/beta/*.bin
|
||||
rm -rf ota/debug/beta/*.bin
|
||||
rm -rf .github .gitignore .gitmodules
|
||||
touch ota/beta/empty
|
||||
touch ota/master/empty
|
||||
touch ota/debug/beta/empty
|
||||
touch ota/debug/master/empty
|
||||
touch webflash/empty
|
||||
- name: Commit binaries to binary
|
||||
uses: stefanzweifel/git-auto-commit-action@v5
|
||||
with:
|
||||
commit_message: "Update binaries"
|
||||
file_pattern: 'ota/* ota/debug/* ota/master/* ota/debug/master/* ota/beta/* ota/debug/beta/* webflash/*'
|
||||
file_pattern: 'ota/* ota/master/* ota/beta/* webflash/*'
|
||||
branch: binary
|
||||
skip_dirty_check: true
|
||||
skip_fetch: true
|
||||
|
||||
@@ -312,7 +312,7 @@ In a browser navigate to the IP address assigned to the ESP32.
|
||||
|
||||
- User: Pick a username to enable HTTP authentication for the Web Configuration, Set to "#" to disable authentication.
|
||||
- Password/Retype password: Pick a password to enable HTTP authentication for the Web Configuration.
|
||||
- Use Digest Authentication (more secure): Enable to use HTTP Digest Authentication instead of HTTP Basic Authentication. Digest authentication is more secure, especially over unencrypted (HTTP) connections.
|
||||
- HTTP Authentication type: Select from Basic, Digest or Form based authentication. Digest authentication is more secure than Basic or Form based authentication, especially over unencrypted (HTTP) connections. Form based authentication works best with password managers. Note: Firefox seems to have issues with basic authentication.
|
||||
|
||||
#### Nuki Lock PIN / Nuki Opener PIN
|
||||
|
||||
|
||||
@@ -303,7 +303,7 @@ String PsychicRequest::getCookie(const char* key)
|
||||
|
||||
// how big is our cookie?
|
||||
size_t size;
|
||||
if (!hasCookie("counter", &size))
|
||||
if (!hasCookie(key, &size))
|
||||
return cookie;
|
||||
|
||||
// allocate cookie buffer... keep it on the stack
|
||||
|
||||
Submodule lib/nuki_ble updated: a579d58a1c...cf762e7dbd
@@ -120,4 +120,5 @@ CONFIG_ESP_WIFI_IRAM_OPT=n
|
||||
CONFIG_ESP_WIFI_RX_IRAM_OPT=n
|
||||
CONFIG_MBEDTLS_DYNAMIC_BUFFER=y
|
||||
CONFIG_LWIP_DHCP_GET_NTP_SRV=y
|
||||
CONFIG_LWIP_SNTP_UPDATE_DELAY=43200000
|
||||
CONFIG_LWIP_SNTP_UPDATE_DELAY=43200000
|
||||
CONFIG_LWIP_SNTP_MAX_SERVERS=3
|
||||
@@ -5,7 +5,7 @@
|
||||
#define NUKI_HUB_VERSION "9.08"
|
||||
#define NUKI_HUB_VERSION_INT (uint32_t)908
|
||||
#define NUKI_HUB_BUILD "unknownbuildnr"
|
||||
#define NUKI_HUB_DATE "2025-01-15"
|
||||
#define NUKI_HUB_DATE "2025-01-17"
|
||||
|
||||
#define GITHUB_LATEST_RELEASE_URL (char*)"https://github.com/technyon/nuki_hub/releases/latest"
|
||||
#define GITHUB_OTA_MANIFEST_URL (char*)"https://raw.githubusercontent.com/technyon/nuki_hub/binary/ota/manifest.json"
|
||||
|
||||
@@ -226,6 +226,7 @@ inline void initPreferences(Preferences* preferences)
|
||||
preferences->putInt(preference_query_interval_configuration, 3600);
|
||||
preferences->putInt(preference_query_interval_battery, 1800);
|
||||
preferences->putInt(preference_query_interval_keypad, 1800);
|
||||
preferences->putInt(preference_http_auth_type, 0);
|
||||
|
||||
preferences->putBool(preference_debug_connect, false);
|
||||
preferences->putBool(preference_debug_communication, false);
|
||||
@@ -233,7 +234,6 @@ inline void initPreferences(Preferences* preferences)
|
||||
preferences->putBool(preference_debug_hex_data, false);
|
||||
preferences->putBool(preference_debug_command, false);
|
||||
preferences->putBool(preference_connect_mode, true);
|
||||
preferences->putBool(preference_http_auth_type, false);
|
||||
preferences->putBool(preference_retain_gpio, false);
|
||||
preferences->putBool(preference_enable_debug_mode, false);
|
||||
|
||||
@@ -508,7 +508,7 @@ private:
|
||||
preference_publish_authdata, preference_publish_debug_info, preference_official_hybrid_enabled, preference_mqtt_hass_enabled, preference_retain_gpio,
|
||||
preference_official_hybrid_actions, preference_official_hybrid_retry, preference_conf_info_enabled, preference_disable_non_json, preference_update_from_mqtt,
|
||||
preference_auth_control_enabled, preference_auth_topic_per_entry, preference_auth_info_enabled, preference_webserial_enabled, preference_hass_device_discovery,
|
||||
preference_ntw_reconfigure, preference_keypad_check_code_enabled, preference_disable_network_not_connected, preference_find_best_rssi, preference_http_auth_type,
|
||||
preference_ntw_reconfigure, preference_keypad_check_code_enabled, preference_disable_network_not_connected, preference_find_best_rssi,
|
||||
preference_debug_connect, preference_debug_communication, preference_debug_readable_data, preference_debug_hex_data, preference_debug_command, preference_connect_mode,
|
||||
preference_lock_force_id, preference_lock_force_doorsensor, preference_lock_force_keypad, preference_opener_force_id, preference_opener_force_keypad, preference_mqtt_ssl_enabled,
|
||||
preference_hybrid_reboot_on_disconnect, preference_lock_gemini_enabled, preference_enable_debug_mode
|
||||
@@ -528,7 +528,7 @@ private:
|
||||
preference_task_size_network, preference_task_size_nuki, preference_authlog_max_entries, preference_keypad_max_entries, preference_timecontrol_max_entries,
|
||||
preference_ble_tx_power, preference_network_custom_mdc, preference_network_custom_clk, preference_network_custom_phy, preference_network_custom_addr,
|
||||
preference_network_custom_irq, preference_network_custom_rst, preference_network_custom_cs, preference_network_custom_sck, preference_network_custom_miso,
|
||||
preference_network_custom_mosi, preference_network_custom_pwr, preference_network_custom_mdio
|
||||
preference_network_custom_mosi, preference_network_custom_pwr, preference_network_custom_mdio, preference_http_auth_type
|
||||
};
|
||||
std::vector<char*> _uintPrefs =
|
||||
{
|
||||
|
||||
@@ -56,8 +56,12 @@ WebCfgServer::WebCfgServer(NukiNetwork* network, Preferences* preferences, bool
|
||||
str = _preferences->getString(preference_cred_password, "");
|
||||
const char *pass = str.c_str();
|
||||
memcpy(&_credPassword, pass, str.length());
|
||||
}
|
||||
|
||||
if (_preferences->getInt(preference_http_auth_type, 0) == 2)
|
||||
{
|
||||
loadSessions();
|
||||
}
|
||||
}
|
||||
_confirmCode = generateConfirmCode();
|
||||
|
||||
#ifndef NUKI_HUB_UPDATER
|
||||
@@ -76,41 +80,115 @@ WebCfgServer::WebCfgServer(NukiNetwork* network, Preferences* preferences, bool
|
||||
#endif
|
||||
}
|
||||
|
||||
void WebCfgServer::initialize()
|
||||
bool WebCfgServer::isAuthenticated(PsychicRequest *request)
|
||||
{
|
||||
_psychicServer->onOpen([&](PsychicClient* client) { Log->printf("[http] connection #%u connected from %s\n", client->socket(), client->localIP().toString().c_str()); });
|
||||
_psychicServer->onClose([&](PsychicClient* client) { Log->printf("[http] connection #%u closed from %s\n", client->socket(), client->localIP().toString().c_str()); });
|
||||
if (request->hasCookie("sessionId")) {
|
||||
String cookie = request->getCookie("sessionId");
|
||||
|
||||
HTTPAuthMethod auth_type = BASIC_AUTH;
|
||||
if (_preferences->getBool(preference_http_auth_type, false))
|
||||
if (_httpSessions[cookie].is<JsonVariant>())
|
||||
{
|
||||
struct timeval time;
|
||||
gettimeofday(&time, NULL);
|
||||
int64_t time_us = (int64_t)time.tv_sec * 1000000L + (int64_t)time.tv_usec;
|
||||
|
||||
if (_httpSessions[cookie].as<signed long long>() > time_us)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
Log->println("Cookie found, but not valid anymore");
|
||||
}
|
||||
}
|
||||
}
|
||||
Log->println("Authentication Failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
esp_err_t WebCfgServer::logoutSession(PsychicRequest *request, PsychicResponse* resp)
|
||||
{
|
||||
Log->print("Logging out");
|
||||
resp->setCookie("sessionId", "", 0, "HttpOnly");
|
||||
|
||||
if (request->hasCookie("sessionId")) {
|
||||
String cookie = request->getCookie("sessionId");
|
||||
_httpSessions.remove(cookie);
|
||||
saveSessions();
|
||||
}
|
||||
else
|
||||
{
|
||||
auth_type = DIGEST_AUTH;
|
||||
Log->print("No session cookie found");
|
||||
}
|
||||
|
||||
_psychicServer->on("/", HTTP_GET, [&](PsychicRequest *request, PsychicResponse* resp)
|
||||
{
|
||||
if(strlen(_credUser) > 0 && strlen(_credPassword) > 0 && !request->authenticate(_credUser, _credPassword))
|
||||
{
|
||||
return request->requestAuthentication(auth_type, "Nuki Hub", "You must log in.");
|
||||
}
|
||||
return buildConfirmHtml(request, resp, "Logging out", 3, true);
|
||||
}
|
||||
|
||||
#ifndef CONFIG_IDF_TARGET_ESP32H2
|
||||
if(!_network->isApOpen())
|
||||
{
|
||||
#endif
|
||||
#ifndef NUKI_HUB_UPDATER
|
||||
return buildHtml(request, resp);
|
||||
#else
|
||||
return buildOtaHtml(request, resp);
|
||||
#endif
|
||||
#ifndef CONFIG_IDF_TARGET_ESP32H2
|
||||
void WebCfgServer::saveSessions()
|
||||
{
|
||||
if(_preferences->getBool(preference_update_time, false))
|
||||
{
|
||||
if (!SPIFFS.begin(true)) {
|
||||
Log->println("SPIFFS Mount Failed");
|
||||
}
|
||||
else
|
||||
{
|
||||
File file = SPIFFS.open("/sessions.json", "w");
|
||||
serializeJson(_httpSessions, file);
|
||||
file.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
void WebCfgServer::loadSessions()
|
||||
{
|
||||
if(_preferences->getBool(preference_update_time, false))
|
||||
{
|
||||
if (!SPIFFS.begin(true)) {
|
||||
Log->println("SPIFFS Mount Failed");
|
||||
}
|
||||
else
|
||||
{
|
||||
return buildWifiConnectHtml(request, resp);
|
||||
File file = SPIFFS.open("/sessions.json", "r");
|
||||
|
||||
if (!file || file.isDirectory()) {
|
||||
Log->println("sessions.json not found");
|
||||
}
|
||||
else
|
||||
{
|
||||
deserializeJson(_httpSessions, file);
|
||||
}
|
||||
file.close();
|
||||
}
|
||||
#endif
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
int WebCfgServer::doAuthentication(PsychicRequest *request)
|
||||
{
|
||||
if(strlen(_credUser) > 0 && strlen(_credPassword) > 0)
|
||||
{
|
||||
int savedAuthType = _preferences->getInt(preference_http_auth_type, 0);
|
||||
if (savedAuthType == 2)
|
||||
{
|
||||
if (!isAuthenticated(request)) {
|
||||
return savedAuthType;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!request->authenticate(_credUser, _credPassword))
|
||||
{
|
||||
return savedAuthType;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 4;
|
||||
}
|
||||
|
||||
void WebCfgServer::initialize()
|
||||
{
|
||||
//_psychicServer->onOpen([&](PsychicClient* client) { Log->printf("[http] connection #%u connected from %s\n", client->socket(), client->localIP().toString().c_str()); });
|
||||
//_psychicServer->onClose([&](PsychicClient* client) { Log->printf("[http] connection #%u closed from %s\n", client->socket(), client->localIP().toString().c_str()); });
|
||||
|
||||
_psychicServer->on("/style.css", HTTP_GET, [&](PsychicRequest *request, PsychicResponse* resp)
|
||||
{
|
||||
return sendCss(request, resp);
|
||||
@@ -129,9 +207,23 @@ void WebCfgServer::initialize()
|
||||
});
|
||||
_psychicServer->on("/savewifi", HTTP_POST, [&](PsychicRequest *request, PsychicResponse* resp)
|
||||
{
|
||||
if(strlen(_credUser) > 0 && strlen(_credPassword) > 0 && !request->authenticate(_credUser, _credPassword))
|
||||
int authReq = doAuthentication(request);
|
||||
|
||||
switch (authReq)
|
||||
{
|
||||
return request->requestAuthentication(auth_type, "Nuki Hub", "You must log in.");
|
||||
case 0:
|
||||
return request->requestAuthentication(BASIC_AUTH, "Nuki Hub", "You must log in.");
|
||||
break;
|
||||
case 1:
|
||||
return request->requestAuthentication(DIGEST_AUTH, "Nuki Hub", "You must log in.");
|
||||
break;
|
||||
case 2:
|
||||
resp->setCode(302);
|
||||
resp->addHeader("Cache-Control", "no-cache");
|
||||
return resp->redirect("/get?page=login");
|
||||
case 4:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
String message = "";
|
||||
@@ -148,9 +240,23 @@ void WebCfgServer::initialize()
|
||||
});
|
||||
_psychicServer->on("/reboot", HTTP_GET, [&](PsychicRequest *request, PsychicResponse* resp)
|
||||
{
|
||||
if(strlen(_credUser) > 0 && strlen(_credPassword) > 0 && !request->authenticate(_credUser, _credPassword))
|
||||
int authReq = doAuthentication(request);
|
||||
|
||||
switch (authReq)
|
||||
{
|
||||
return request->requestAuthentication(auth_type, "Nuki Hub", "You must log in.");
|
||||
case 0:
|
||||
return request->requestAuthentication(BASIC_AUTH, "Nuki Hub", "You must log in.");
|
||||
break;
|
||||
case 1:
|
||||
return request->requestAuthentication(DIGEST_AUTH, "Nuki Hub", "You must log in.");
|
||||
break;
|
||||
case 2:
|
||||
resp->setCode(302);
|
||||
resp->addHeader("Cache-Control", "no-cache");
|
||||
return resp->redirect("/get?page=login");
|
||||
case 4:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
String value = "";
|
||||
@@ -169,6 +275,8 @@ void WebCfgServer::initialize()
|
||||
|
||||
if(value != _confirmCode)
|
||||
{
|
||||
resp->setCode(302);
|
||||
resp->addHeader("Cache-Control", "no-cache");
|
||||
return resp->redirect("/");
|
||||
}
|
||||
esp_err_t res = buildConfirmHtml(request, resp, "Rebooting...", 2, true);
|
||||
@@ -191,16 +299,44 @@ void WebCfgServer::initialize()
|
||||
value = p->value();
|
||||
}
|
||||
}
|
||||
|
||||
if (value != "status")
|
||||
int authReq = doAuthentication(request);
|
||||
|
||||
if (value != "status" && value != "login" && value != "logout")
|
||||
{
|
||||
if(strlen(_credUser) > 0 && strlen(_credPassword) > 0 && !request->authenticate(_credUser, _credPassword))
|
||||
switch (authReq)
|
||||
{
|
||||
return request->requestAuthentication(auth_type, "Nuki Hub", "You must log in.");
|
||||
case 0:
|
||||
return request->requestAuthentication(BASIC_AUTH, "Nuki Hub", "You must log in.");
|
||||
break;
|
||||
case 1:
|
||||
return request->requestAuthentication(DIGEST_AUTH, "Nuki Hub", "You must log in.");
|
||||
break;
|
||||
case 2:
|
||||
resp->setCode(302);
|
||||
resp->addHeader("Cache-Control", "no-cache");
|
||||
return resp->redirect("/get?page=login");
|
||||
case 4:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (value == "status" && authReq != 4)
|
||||
{
|
||||
resp->setCode(200);
|
||||
resp->setContentType("application/json");
|
||||
resp->setContent("{}");
|
||||
return resp->send();
|
||||
}
|
||||
|
||||
if (value == "reboot")
|
||||
if (value == "login")
|
||||
{
|
||||
return buildLoginHtml(request, resp);
|
||||
}
|
||||
else if (value == "logout")
|
||||
{
|
||||
return logoutSession(request, resp);
|
||||
}
|
||||
else if (value == "reboot")
|
||||
{
|
||||
String value = "";
|
||||
if(request->hasParam("CONFIRMTOKEN"))
|
||||
@@ -218,6 +354,8 @@ void WebCfgServer::initialize()
|
||||
|
||||
if(value != _confirmCode)
|
||||
{
|
||||
resp->setCode(302);
|
||||
resp->addHeader("Cache-Control", "no-cache");
|
||||
return resp->redirect("/");
|
||||
}
|
||||
esp_err_t res = buildConfirmHtml(request, resp, "Rebooting...", 2, true);
|
||||
@@ -250,18 +388,7 @@ void WebCfgServer::initialize()
|
||||
}
|
||||
else if (value == "status")
|
||||
{
|
||||
if(request->hasParam("token"))
|
||||
{
|
||||
const PsychicWebParameter* p2 = request->getParam("token");
|
||||
if(p2->value().toInt() == _randomInt)
|
||||
{
|
||||
return buildStatusHtml(request, resp);
|
||||
}
|
||||
}
|
||||
resp->setCode(200);
|
||||
resp->setContentType("text/html");
|
||||
resp->setContent("");
|
||||
return resp->send();
|
||||
return buildStatusHtml(request, resp);
|
||||
}
|
||||
else if (value == "acclvl")
|
||||
{
|
||||
@@ -337,6 +464,8 @@ void WebCfgServer::initialize()
|
||||
}
|
||||
if(value != _confirmCode)
|
||||
{
|
||||
resp->setCode(302);
|
||||
resp->addHeader("Cache-Control", "no-cache");
|
||||
return resp->redirect("/");
|
||||
}
|
||||
if(!_allowRestartToPortal)
|
||||
@@ -356,7 +485,8 @@ void WebCfgServer::initialize()
|
||||
}
|
||||
else if (value == "otadebug")
|
||||
{
|
||||
return buildOtaHtml(request, resp, true);
|
||||
return buildOtaHtml(request, resp);
|
||||
//return buildOtaHtml(request, resp, true);
|
||||
}
|
||||
else if (value == "reboottoota")
|
||||
{
|
||||
@@ -376,6 +506,8 @@ void WebCfgServer::initialize()
|
||||
|
||||
if(value != _confirmCode)
|
||||
{
|
||||
resp->setCode(302);
|
||||
resp->addHeader("Cache-Control", "no-cache");
|
||||
return resp->redirect("/");
|
||||
}
|
||||
esp_err_t res = buildConfirmHtml(request, resp, "Rebooting to other partition...", 2, true);
|
||||
@@ -389,36 +521,21 @@ void WebCfgServer::initialize()
|
||||
#ifndef NUKI_HUB_UPDATER
|
||||
return processUpdate(request, resp);
|
||||
#else
|
||||
resp->setCode(302);
|
||||
resp->addHeader("Cache-Control", "no-cache");
|
||||
return resp->redirect("/");
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifndef CONFIG_IDF_TARGET_ESP32H2
|
||||
if(!_network->isApOpen())
|
||||
{
|
||||
#endif
|
||||
#ifndef NUKI_HUB_UPDATER
|
||||
return buildHtml(request, resp);
|
||||
#else
|
||||
return buildOtaHtml(request, resp);
|
||||
#endif
|
||||
#ifndef CONFIG_IDF_TARGET_ESP32H2
|
||||
}
|
||||
else
|
||||
{
|
||||
return buildWifiConnectHtml(request, resp);
|
||||
}
|
||||
#endif
|
||||
Log->println("Page not found, loading index");
|
||||
resp->setCode(302);
|
||||
resp->addHeader("Cache-Control", "no-cache");
|
||||
return resp->redirect("/");
|
||||
}
|
||||
});
|
||||
_psychicServer->on("/post", HTTP_POST, [&](PsychicRequest *request, PsychicResponse* resp)
|
||||
{
|
||||
if(strlen(_credUser) > 0 && strlen(_credPassword) > 0 && !request->authenticate(_credUser, _credPassword))
|
||||
{
|
||||
return request->requestAuthentication(auth_type, "Nuki Hub", "You must log in.");
|
||||
}
|
||||
|
||||
String value = "";
|
||||
if(request->hasParam("page"))
|
||||
{
|
||||
@@ -429,8 +546,46 @@ void WebCfgServer::initialize()
|
||||
}
|
||||
}
|
||||
|
||||
if (value != "login")
|
||||
{
|
||||
int authReq = doAuthentication(request);
|
||||
|
||||
switch (authReq)
|
||||
{
|
||||
case 0:
|
||||
return request->requestAuthentication(BASIC_AUTH, "Nuki Hub", "You must log in.");
|
||||
break;
|
||||
case 1:
|
||||
return request->requestAuthentication(DIGEST_AUTH, "Nuki Hub", "You must log in.");
|
||||
break;
|
||||
case 2:
|
||||
resp->setCode(302);
|
||||
resp->addHeader("Cache-Control", "no-cache");
|
||||
return resp->redirect("/get?page=login");
|
||||
case 4:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (value == "login")
|
||||
{
|
||||
bool loggedIn = processLogin(request, resp);
|
||||
if (loggedIn)
|
||||
{
|
||||
resp->setCode(302);
|
||||
resp->addHeader("Cache-Control", "no-cache");
|
||||
return resp->redirect("/");
|
||||
}
|
||||
else
|
||||
{
|
||||
resp->setCode(302);
|
||||
resp->addHeader("Cache-Control", "no-cache");
|
||||
return resp->redirect("/get?page=login");
|
||||
}
|
||||
}
|
||||
#ifndef NUKI_HUB_UPDATER
|
||||
if (value == "savecfg")
|
||||
else if (value == "savecfg")
|
||||
{
|
||||
String message = "";
|
||||
bool restart = processArgs(request, resp, message);
|
||||
@@ -474,10 +629,8 @@ void WebCfgServer::initialize()
|
||||
bool restart = processImport(request, resp, message);
|
||||
return buildConfirmHtml(request, resp, message, 3, true);
|
||||
}
|
||||
else
|
||||
#else
|
||||
if (1 == 1)
|
||||
#endif
|
||||
else
|
||||
{
|
||||
#ifndef CONFIG_IDF_TARGET_ESP32H2
|
||||
if(!_network->isApOpen())
|
||||
@@ -501,19 +654,44 @@ void WebCfgServer::initialize()
|
||||
PsychicUploadHandler *updateHandler = new PsychicUploadHandler();
|
||||
updateHandler->onUpload([&](PsychicRequest *request, const String& filename, uint64_t index, uint8_t *data, size_t len, bool last)
|
||||
{
|
||||
if(strlen(_credUser) > 0 && strlen(_credPassword) > 0 && !request->authenticate(_credUser, _credPassword))
|
||||
{
|
||||
return request->requestAuthentication(auth_type, "Nuki Hub", "You must log in.");
|
||||
}
|
||||
int authReq = doAuthentication(request);
|
||||
|
||||
switch (authReq)
|
||||
{
|
||||
case 0:
|
||||
return request->requestAuthentication(BASIC_AUTH, "Nuki Hub", "You must log in.");
|
||||
break;
|
||||
case 1:
|
||||
return request->requestAuthentication(DIGEST_AUTH, "Nuki Hub", "You must log in.");
|
||||
break;
|
||||
case 2:
|
||||
return ESP_FAIL;
|
||||
case 4:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return handleOtaUpload(request, filename, index, data, len, last);
|
||||
});
|
||||
|
||||
updateHandler->onRequest([&](PsychicRequest* request, PsychicResponse* resp)
|
||||
{
|
||||
if(strlen(_credUser) > 0 && strlen(_credPassword) > 0 && !request->authenticate(_credUser, _credPassword))
|
||||
int authReq = doAuthentication(request);
|
||||
|
||||
switch (authReq)
|
||||
{
|
||||
return request->requestAuthentication(auth_type, "Nuki Hub", "You must log in.");
|
||||
case 0:
|
||||
return request->requestAuthentication(BASIC_AUTH, "Nuki Hub", "You must log in.");
|
||||
break;
|
||||
case 1:
|
||||
return request->requestAuthentication(DIGEST_AUTH, "Nuki Hub", "You must log in.");
|
||||
break;
|
||||
case 2:
|
||||
resp->setCode(302);
|
||||
resp->addHeader("Cache-Control", "no-cache");
|
||||
return resp->redirect("/get?page=login");
|
||||
case 4:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
String result;
|
||||
@@ -546,6 +724,47 @@ void WebCfgServer::initialize()
|
||||
_psychicServer->on("/uploadota", HTTP_POST, updateHandler);
|
||||
//Update.onProgress(printProgress);
|
||||
}
|
||||
|
||||
_psychicServer->on("/", HTTP_GET, [&](PsychicRequest *request, PsychicResponse* resp)
|
||||
{
|
||||
int authReq = doAuthentication(request);
|
||||
|
||||
switch (authReq)
|
||||
{
|
||||
case 0:
|
||||
return request->requestAuthentication(BASIC_AUTH, "Nuki Hub", "You must log in.");
|
||||
break;
|
||||
case 1:
|
||||
return request->requestAuthentication(DIGEST_AUTH, "Nuki Hub", "You must log in.");
|
||||
break;
|
||||
case 2:
|
||||
resp->setCode(302);
|
||||
resp->addHeader("Cache-Control", "no-cache");
|
||||
return resp->redirect("/get?page=login");
|
||||
break;
|
||||
case 4:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
#ifndef CONFIG_IDF_TARGET_ESP32H2
|
||||
if(!_network->isApOpen())
|
||||
{
|
||||
#endif
|
||||
#ifndef NUKI_HUB_UPDATER
|
||||
return buildHtml(request, resp);
|
||||
#else
|
||||
return buildOtaHtml(request, resp);
|
||||
#endif
|
||||
#ifndef CONFIG_IDF_TARGET_ESP32H2
|
||||
}
|
||||
else
|
||||
{
|
||||
return buildWifiConnectHtml(request, resp);
|
||||
}
|
||||
#endif
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
void WebCfgServer::printCheckBox(PsychicStreamResponse *response, const char *token, const char *description, const bool value, const char *htmlClass)
|
||||
@@ -1266,6 +1485,54 @@ void WebCfgServer::printInputField(PsychicStreamResponse *response,
|
||||
printInputField(response, token, description, valueStr, maxLength, args);
|
||||
}
|
||||
|
||||
esp_err_t WebCfgServer::buildLoginHtml(PsychicRequest *request, PsychicResponse* resp)
|
||||
{
|
||||
PsychicStreamResponse response(resp, "text/html");
|
||||
response.beginSend();
|
||||
response.print("<html><head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">");
|
||||
response.print("<style>form{border:3px solid #f1f1f1; max-width: 400px;}input[type=password],input[type=text]{width:100%;padding:12px 20px;margin:8px 0;display:inline-block;border:1px solid #ccc;box-sizing:border-box}button{background-color:#04aa6d;color:#fff;padding:14px 20px;margin:8px 0;border:none;cursor:pointer;width:100%}button:hover{opacity:.8}.container{padding:16px}span.password{float:right;padding-top:16px}@media screen and (max-width:300px){span.psw{display:block;float:none}}</style>");
|
||||
response.print("<html><head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">");
|
||||
response.print("</head><body><center><h2>NukiHub login</h2><form action=\"/post?page=login\" method=\"post\">");
|
||||
response.print("<div class=\"container\"><label for=\"username\"><b>Username</b></label><input type=\"text\" placeholder=\"Enter Username\" name=\"username\" required>");
|
||||
response.print("<label for=\"password\"><b>Password</b></label><input type=\"password\" placeholder=\"Enter Password\" name=\"password\" required>");
|
||||
response.print("<button type=\"submit\">Login</button><label><input type=\"checkbox\" checked=\"checked\" name=\"remember\"> Remember me</label></div>");
|
||||
response.print("</form></center></body></html>");
|
||||
return response.endSend();
|
||||
}
|
||||
|
||||
bool WebCfgServer::processLogin(PsychicRequest *request, PsychicResponse* resp)
|
||||
{
|
||||
if(request->hasParam("username") && request->hasParam("password"))
|
||||
{
|
||||
const PsychicWebParameter* user = request->getParam("username");
|
||||
const PsychicWebParameter* pass = request->getParam("password");
|
||||
if(user->value() != "" && pass->value() != "")
|
||||
{
|
||||
if (user->value() == _preferences->getString(preference_cred_user, "") && pass->value() == _preferences->getString(preference_cred_password, ""))
|
||||
{
|
||||
char buffer[33];
|
||||
int i;
|
||||
int64_t durationLength = 60*60*24*30;
|
||||
for (i = 0; i < 4; i++) {
|
||||
sprintf(buffer + (i * 8), "%08lx", (unsigned long int)esp_random());
|
||||
}
|
||||
if(!request->hasParam("remember")) {
|
||||
durationLength = 60*60;
|
||||
}
|
||||
resp->setCookie("sessionId", buffer, durationLength, "HttpOnly");
|
||||
|
||||
struct timeval time;
|
||||
gettimeofday(&time, NULL);
|
||||
int64_t time_us = (int64_t)time.tv_sec * 1000000L + (int64_t)time.tv_usec;
|
||||
_httpSessions[buffer] = time_us + (durationLength*1000000L);
|
||||
saveSessions();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifndef NUKI_HUB_UPDATER
|
||||
esp_err_t WebCfgServer::sendSettings(PsychicRequest *request, PsychicResponse* resp)
|
||||
{
|
||||
@@ -2788,9 +3055,9 @@ bool WebCfgServer::processArgs(PsychicRequest *request, PsychicResponse* resp, S
|
||||
}
|
||||
else if(key == "CREDDIGEST")
|
||||
{
|
||||
if(_preferences->getBool(preference_http_auth_type, false) != (value == "1"))
|
||||
if(_preferences->getInt(preference_http_auth_type, 0) != value.toInt())
|
||||
{
|
||||
_preferences->putBool(preference_http_auth_type, (value == "1"));
|
||||
_preferences->putInt(preference_http_auth_type, value.toInt());
|
||||
Log->print(("Setting changed: "));
|
||||
Log->println(key);
|
||||
configChanged = true;
|
||||
@@ -3914,8 +4181,7 @@ esp_err_t WebCfgServer::buildCustomNetworkConfigHtml(PsychicRequest *request, Ps
|
||||
|
||||
esp_err_t WebCfgServer::buildHtml(PsychicRequest *request, PsychicResponse* resp)
|
||||
{
|
||||
_randomInt = esp_random();
|
||||
String header = (String)"<script>let intervalId; window.onload = function() { updateInfo(); intervalId = setInterval(updateInfo, 3000); }; function updateInfo() { var request = new XMLHttpRequest(); request.open('GET', '/get?page=status&token=" + _randomInt + "', true); request.onload = () => { const obj = JSON.parse(request.responseText); if (obj.stop == 1) { clearInterval(intervalId); } for (var key of Object.keys(obj)) { if(key=='ota' && document.getElementById(key) !== null) { document.getElementById(key).innerText = \"<a href='/ota'>\" + obj[key] + \"</a>\"; } else if(document.getElementById(key) !== null) { document.getElementById(key).innerText = obj[key]; } } }; request.send(); }</script>";
|
||||
String header = (String)"<script>let intervalId; window.onload = function() { updateInfo(); intervalId = setInterval(updateInfo, 3000); }; function updateInfo() { var request = new XMLHttpRequest(); request.open('GET', '/get?page=status', true); request.onload = () => { const obj = JSON.parse(request.responseText); if (obj.stop == 1) { clearInterval(intervalId); } for (var key of Object.keys(obj)) { if(key=='ota' && document.getElementById(key) !== null) { document.getElementById(key).innerText = \"<a href='/ota'>\" + obj[key] + \"</a>\"; } else if(document.getElementById(key) !== null) { document.getElementById(key).innerText = obj[key]; } } }; request.send(); }</script>";
|
||||
PsychicStreamResponse response(resp, "text/html");
|
||||
response.beginSend();
|
||||
buildHtmlHeader(&response, header);
|
||||
@@ -4008,6 +4274,10 @@ esp_err_t WebCfgServer::buildHtml(PsychicRequest *request, PsychicResponse* resp
|
||||
#endif
|
||||
String rebooturl = "/get?page=reboot&CONFIRMTOKEN=" + _confirmCode;
|
||||
buildNavigationMenuEntry(&response, "Reboot Nuki Hub", rebooturl.c_str());
|
||||
if (_preferences->getInt(preference_http_auth_type, 0) == 2)
|
||||
{
|
||||
buildNavigationMenuEntry(&response, "Logout", "/get?page=logout");
|
||||
}
|
||||
response.print("</ul></body></html>");
|
||||
return response.endSend();
|
||||
}
|
||||
@@ -4024,7 +4294,13 @@ esp_err_t WebCfgServer::buildCredHtml(PsychicRequest *request, PsychicResponse*
|
||||
printInputField(&response, "CREDUSER", "User (# to clear)", _preferences->getString(preference_cred_user).c_str(), 30, "id=\"inputuser\"", false, true);
|
||||
printInputField(&response, "CREDPASS", "Password", "*", 30, "id=\"inputpass\"", true, true);
|
||||
printInputField(&response, "CREDPASSRE", "Retype password", "*", 30, "id=\"inputpass2\"", true);
|
||||
printCheckBox(&response, "CREDDIGEST", "Use Digest Authentication (more secure)", _preferences->getBool(preference_http_auth_type, false), "");
|
||||
|
||||
std::vector<std::pair<String, String>> httpAuthOptions;
|
||||
httpAuthOptions.push_back(std::make_pair("0", "Basic"));
|
||||
httpAuthOptions.push_back(std::make_pair("1", "Digest"));
|
||||
httpAuthOptions.push_back(std::make_pair("2", "Form"));
|
||||
|
||||
printDropDown(&response, "CREDDIGEST", "HTTP Authentication type", String(_preferences->getInt(preference_http_auth_type, 0)), httpAuthOptions, "");
|
||||
response.print("</table>");
|
||||
response.print("<br><input type=\"submit\" name=\"submit\" value=\"Save\">");
|
||||
response.print("</form><script>function testcreds() { var input_user = document.getElementById(\"inputuser\").value; var input_pass = document.getElementById(\"inputpass\").value; var input_pass2 = document.getElementById(\"inputpass2\").value; var pattern = /^[ -~]*$/; if(input_user == '#' || input_user == '') { return true; } if (input_pass != input_pass2) { alert('Passwords do not match'); return false;} if(!pattern.test(input_user) || !pattern.test(input_pass)) { alert('Only non unicode characters are allowed in username and password'); return false;} else { return true; } }</script>");
|
||||
@@ -4964,7 +5240,7 @@ esp_err_t WebCfgServer::buildInfoHtml(PsychicRequest *request, PsychicResponse*
|
||||
response.print("\nWeb configurator password: ");
|
||||
response.print(_preferences->getString(preference_cred_password, "").length() > 0 ? "***" : "Not set");
|
||||
response.print("\nWeb configurator authentication: ");
|
||||
response.print(_preferences->getBool(preference_http_auth_type, false) ? "Digest" : "Basic");
|
||||
response.print(_preferences->getInt(preference_http_auth_type, 0) == 0 ? "Basic" : _preferences->getInt(preference_http_auth_type, 0) == 1 ? "Digest" : "Form");
|
||||
response.print("\nWeb configurator enabled: ");
|
||||
response.print(_preferences->getBool(preference_webserver_enabled, true) ? "Yes" : "No");
|
||||
response.print("\nHTTP SSL: ");
|
||||
@@ -5652,6 +5928,7 @@ esp_err_t WebCfgServer::processUpdate(PsychicRequest *request, PsychicResponse*
|
||||
|
||||
if(request->hasParam("beta"))
|
||||
{
|
||||
/*
|
||||
if(request->hasParam("debug"))
|
||||
{
|
||||
res = buildConfirmHtml(request, resp, "Rebooting to update Nuki Hub and Nuki Hub updater<br/>Updating to latest DEBUG BETA version", 2, true);
|
||||
@@ -5660,13 +5937,15 @@ esp_err_t WebCfgServer::processUpdate(PsychicRequest *request, PsychicResponse*
|
||||
}
|
||||
else
|
||||
{
|
||||
res = buildConfirmHtml(request, resp, "Rebooting to update Nuki Hub and Nuki Hub updater<br/>Updating to latest BETA version", 2, true);
|
||||
_preferences->putString(preference_ota_updater_url, GITHUB_BETA_UPDATER_BINARY_URL);
|
||||
_preferences->putString(preference_ota_main_url, GITHUB_BETA_RELEASE_BINARY_URL);
|
||||
}
|
||||
*/
|
||||
res = buildConfirmHtml(request, resp, "Rebooting to update Nuki Hub and Nuki Hub updater<br/>Updating to latest BETA version", 2, true);
|
||||
_preferences->putString(preference_ota_updater_url, GITHUB_BETA_UPDATER_BINARY_URL);
|
||||
_preferences->putString(preference_ota_main_url, GITHUB_BETA_RELEASE_BINARY_URL);
|
||||
//}
|
||||
}
|
||||
else if(request->hasParam("master"))
|
||||
{
|
||||
/*
|
||||
if(request->hasParam("debug"))
|
||||
{
|
||||
res = buildConfirmHtml(request, resp, "Rebooting to update Nuki Hub and Nuki Hub updater<br/>Updating to latest DEBUG DEVELOPMENT version", 2, true);
|
||||
@@ -5675,10 +5954,11 @@ esp_err_t WebCfgServer::processUpdate(PsychicRequest *request, PsychicResponse*
|
||||
}
|
||||
else
|
||||
{
|
||||
res = buildConfirmHtml(request, resp, "Rebooting to update Nuki Hub and Nuki Hub updater<br/>Updating to latest DEVELOPMENT version", 2, true);
|
||||
_preferences->putString(preference_ota_updater_url, GITHUB_MASTER_UPDATER_BINARY_URL);
|
||||
_preferences->putString(preference_ota_main_url, GITHUB_MASTER_RELEASE_BINARY_URL);
|
||||
}
|
||||
*/
|
||||
res = buildConfirmHtml(request, resp, "Rebooting to update Nuki Hub and Nuki Hub updater<br/>Updating to latest DEVELOPMENT version", 2, true);
|
||||
_preferences->putString(preference_ota_updater_url, GITHUB_MASTER_UPDATER_BINARY_URL);
|
||||
_preferences->putString(preference_ota_main_url, GITHUB_MASTER_RELEASE_BINARY_URL);
|
||||
//}
|
||||
}
|
||||
#if defined(CONFIG_IDF_TARGET_ESP32S3)
|
||||
else if(request->hasParam("other"))
|
||||
@@ -5690,6 +5970,7 @@ esp_err_t WebCfgServer::processUpdate(PsychicRequest *request, PsychicResponse*
|
||||
#endif
|
||||
else
|
||||
{
|
||||
/*
|
||||
if(request->hasParam("debug"))
|
||||
{
|
||||
res = buildConfirmHtml(request, resp, "Rebooting to update Nuki Hub and Nuki Hub updater<br/>Updating to latest DEBUG RELEASE version", 2, true);
|
||||
@@ -5698,10 +5979,11 @@ esp_err_t WebCfgServer::processUpdate(PsychicRequest *request, PsychicResponse*
|
||||
}
|
||||
else
|
||||
{
|
||||
res = buildConfirmHtml(request, resp, "Rebooting to update Nuki Hub and Nuki Hub updater<br/>Updating to latest RELEASE version", 2, true);
|
||||
_preferences->putString(preference_ota_updater_url, GITHUB_LATEST_UPDATER_BINARY_URL);
|
||||
_preferences->putString(preference_ota_main_url, GITHUB_LATEST_RELEASE_BINARY_URL);
|
||||
}
|
||||
*/
|
||||
res = buildConfirmHtml(request, resp, "Rebooting to update Nuki Hub and Nuki Hub updater<br/>Updating to latest RELEASE version", 2, true);
|
||||
_preferences->putString(preference_ota_updater_url, GITHUB_LATEST_UPDATER_BINARY_URL);
|
||||
_preferences->putString(preference_ota_main_url, GITHUB_LATEST_RELEASE_BINARY_URL);
|
||||
//}
|
||||
}
|
||||
waitAndProcess(true, 1000);
|
||||
restartEsp(RestartReason::OTAReboot);
|
||||
|
||||
@@ -100,7 +100,14 @@ private:
|
||||
std::vector<int> _rssiList;
|
||||
String generateConfirmCode();
|
||||
String _confirmCode = "----";
|
||||
|
||||
|
||||
void saveSessions();
|
||||
void loadSessions();
|
||||
esp_err_t logoutSession(PsychicRequest *request, PsychicResponse* resp);
|
||||
bool isAuthenticated(PsychicRequest *request);
|
||||
bool processLogin(PsychicRequest *request, PsychicResponse* resp);
|
||||
int doAuthentication(PsychicRequest *request);
|
||||
esp_err_t buildLoginHtml(PsychicRequest *request, PsychicResponse* resp);
|
||||
esp_err_t buildSSIDListHtml(PsychicRequest *request, PsychicResponse* resp);
|
||||
esp_err_t buildConfirmHtml(PsychicRequest *request, PsychicResponse* resp, const String &message, uint32_t redirectDelay = 5, bool redirect = false, String redirectTo = "/");
|
||||
esp_err_t buildOtaHtml(PsychicRequest *request, PsychicResponse* resp, bool debug = false);
|
||||
@@ -128,6 +135,6 @@ private:
|
||||
bool _allowRestartToPortal = false;
|
||||
uint8_t _partitionType = 0;
|
||||
size_t _otaContentLen = 0;
|
||||
uint32_t _randomInt = 0;
|
||||
String _hostname;
|
||||
JsonDocument _httpSessions;
|
||||
};
|
||||
|
||||
30
src/main.cpp
30
src/main.cpp
@@ -10,6 +10,7 @@
|
||||
#include "esp32-hal-log.h"
|
||||
#include "hal/wdt_hal.h"
|
||||
#include "esp_chip_info.h"
|
||||
#include "esp_netif_sntp.h"
|
||||
#ifdef CONFIG_SOC_SPIRAM_SUPPORTED
|
||||
#include "esp_psram.h"
|
||||
#include "FS.h"
|
||||
@@ -29,7 +30,6 @@
|
||||
#include "RestartReason.h"
|
||||
#include "EspMillis.h"
|
||||
#include "NimBLEDevice.h"
|
||||
#include "esp_netif_sntp.h"
|
||||
|
||||
/*
|
||||
#ifdef DEBUG_NUKIHUB
|
||||
@@ -38,8 +38,6 @@
|
||||
#endif
|
||||
*/
|
||||
|
||||
char log_print_buffer[1024];
|
||||
|
||||
NukiNetworkLock* networkLock = nullptr;
|
||||
NukiNetworkOpener* networkOpener = nullptr;
|
||||
BleScanner::Scanner* bleScanner = nullptr;
|
||||
@@ -71,6 +69,8 @@ int64_t restartTs = 10 * 60 * 1000;
|
||||
|
||||
#endif
|
||||
|
||||
char log_print_buffer[1024];
|
||||
|
||||
PsychicHttpServer* psychicServer = nullptr;
|
||||
PsychicHttpsServer* psychicSSLServer = nullptr;
|
||||
NukiNetwork* network = nullptr;
|
||||
@@ -97,7 +97,6 @@ RestartReason currentRestartReason = RestartReason::NotApplicable;
|
||||
TaskHandle_t otaTaskHandle = nullptr;
|
||||
TaskHandle_t networkTaskHandle = nullptr;
|
||||
|
||||
#ifndef NUKI_HUB_UPDATER
|
||||
ssize_t write_fn(void* cookie, const char* buf, ssize_t size)
|
||||
{
|
||||
Log->write((uint8_t *)buf, (size_t)size);
|
||||
@@ -157,7 +156,6 @@ void setReroute()
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
uint8_t checkPartition()
|
||||
{
|
||||
@@ -181,6 +179,10 @@ uint8_t checkPartition()
|
||||
}
|
||||
}
|
||||
|
||||
void cbSyncTime(struct timeval *tv) {
|
||||
Log->println("NTP time synched");
|
||||
}
|
||||
|
||||
void networkTask(void *pvParameters)
|
||||
{
|
||||
int64_t networkLoopTs = 0;
|
||||
@@ -204,13 +206,15 @@ void networkTask(void *pvParameters)
|
||||
network->update();
|
||||
bool connected = network->isConnected();
|
||||
|
||||
#ifndef NUKI_HUB_UPDATER
|
||||
if(connected && reroute)
|
||||
{
|
||||
if(preferences->getBool(preference_update_time, false))
|
||||
{
|
||||
esp_netif_sntp_start();
|
||||
}
|
||||
reroute = false;
|
||||
setReroute();
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef NUKI_HUB_UPDATER
|
||||
wifiConnected = network->wifiConnected();
|
||||
@@ -503,10 +507,6 @@ void setupTasks(bool ota)
|
||||
}
|
||||
}
|
||||
|
||||
void cbSyncTime(struct timeval *tv) {
|
||||
Log->println(("NTP time synched"));
|
||||
}
|
||||
|
||||
void setup()
|
||||
{
|
||||
//Set Log level to error for all TAGS
|
||||
@@ -822,16 +822,14 @@ void setup()
|
||||
}
|
||||
#endif
|
||||
*/
|
||||
}
|
||||
|
||||
if(preferences->getBool(preference_update_time, false))
|
||||
{
|
||||
esp_sntp_config_t config = ESP_NETIF_SNTP_DEFAULT_CONFIG(preferences->getString(preference_time_server, "pool.ntp.org").c_str());
|
||||
String timeserver = preferences->getString(preference_time_server, "pool.ntp.org");
|
||||
esp_sntp_config_t config = ESP_NETIF_SNTP_DEFAULT_CONFIG(timeserver.c_str());
|
||||
config.start = false;
|
||||
config.server_from_dhcp = true;
|
||||
config.renew_servers_after_new_IP = true;
|
||||
config.index_of_first_server = 1;
|
||||
|
||||
|
||||
if (network->networkDeviceType() == NetworkDeviceType::WiFi)
|
||||
{
|
||||
config.ip_event_to_renew = IP_EVENT_STA_GOT_IP;
|
||||
|
||||
Reference in New Issue
Block a user