From 43fd09571480cd17158fd114fc50d3c9df727a48 Mon Sep 17 00:00:00 2001 From: Yurii Date: Mon, 2 Dec 2024 06:26:03 +0300 Subject: [PATCH] fix: digest auth changed to basic Digest auth not working on ios #99 --- src/PortalTask.h | 101 ++++++++++++++-------------------- src_data/pages/dashboard.html | 21 +++++-- src_data/pages/index.html | 6 +- src_data/pages/network.html | 6 +- src_data/pages/sensors.html | 12 +++- src_data/pages/settings.html | 6 +- src_data/scripts/lang.js | 2 +- src_data/scripts/utils.js | 38 ++++++++----- 8 files changed, 106 insertions(+), 86 deletions(-) diff --git a/src/PortalTask.h b/src/PortalTask.h index 184ddfb..7a77651 100644 --- a/src/PortalTask.h +++ b/src/PortalTask.h @@ -108,8 +108,8 @@ protected: // dashboard page auto dashboardPage = (new StaticPage("/dashboard.html", &LittleFS, F("/pages/dashboard.html"), PORTAL_CACHE)) ->setBeforeSendCallback([this]() { - if (this->isAuthRequired() && !this->webServer->authenticate(settings.portal.login, settings.portal.password)) { - this->webServer->requestAuthentication(DIGEST_AUTH); + if (this->isAuthRequired() && !this->isValidCredentials()) { + this->webServer->requestAuthentication(BASIC_AUTH); return false; } @@ -119,11 +119,9 @@ protected: // restart this->webServer->on(F("/restart.html"), HTTP_GET, [this]() { - if (this->isAuthRequired()) { - if (!this->webServer->authenticate(settings.portal.login, settings.portal.password)) { - this->webServer->send(401); - return; - } + if (this->isAuthRequired() && !this->isValidCredentials()) { + this->webServer->requestAuthentication(BASIC_AUTH); + return; } vars.actions.restart = true; @@ -134,8 +132,8 @@ protected: // network settings page auto networkPage = (new StaticPage("/network.html", &LittleFS, F("/pages/network.html"), PORTAL_CACHE)) ->setBeforeSendCallback([this]() { - if (this->isAuthRequired() && !this->webServer->authenticate(settings.portal.login, settings.portal.password)) { - this->webServer->requestAuthentication(DIGEST_AUTH); + if (this->isAuthRequired() && !this->isValidCredentials()) { + this->webServer->requestAuthentication(BASIC_AUTH); return false; } @@ -146,8 +144,8 @@ protected: // settings page auto settingsPage = (new StaticPage("/settings.html", &LittleFS, F("/pages/settings.html"), PORTAL_CACHE)) ->setBeforeSendCallback([this]() { - if (this->isAuthRequired() && !this->webServer->authenticate(settings.portal.login, settings.portal.password)) { - this->webServer->requestAuthentication(DIGEST_AUTH); + if (this->isAuthRequired() && !this->isValidCredentials()) { + this->webServer->requestAuthentication(BASIC_AUTH); return false; } @@ -158,8 +156,8 @@ protected: // sensors page auto sensorsPage = (new StaticPage("/sensors.html", &LittleFS, F("/pages/sensors.html"), PORTAL_CACHE)) ->setBeforeSendCallback([this]() { - if (this->isAuthRequired() && !this->webServer->authenticate(settings.portal.login, settings.portal.password)) { - this->webServer->requestAuthentication(DIGEST_AUTH); + if (this->isAuthRequired() && !this->isValidCredentials()) { + this->webServer->requestAuthentication(BASIC_AUTH); return false; } @@ -170,8 +168,8 @@ protected: // upgrade page auto upgradePage = (new StaticPage("/upgrade.html", &LittleFS, F("/pages/upgrade.html"), PORTAL_CACHE)) ->setBeforeSendCallback([this]() { - if (this->isAuthRequired() && !this->webServer->authenticate(settings.portal.login, settings.portal.password)) { - this->webServer->requestAuthentication(DIGEST_AUTH); + if (this->isAuthRequired() && !this->isValidCredentials()) { + this->webServer->requestAuthentication(BASIC_AUTH); return false; } @@ -181,7 +179,7 @@ protected: // OTA auto upgradeHandler = (new UpgradeHandler("/api/upgrade"))->setCanUploadCallback([this](const String& uri) { - if (this->isAuthRequired() && !this->webServer->authenticate(settings.portal.login, settings.portal.password)) { + if (this->isAuthRequired() && !this->isValidCredentials()) { this->webServer->sendHeader(F("Connection"), F("close")); this->webServer->send(401); return false; @@ -222,10 +220,8 @@ protected: // backup this->webServer->on(F("/api/backup/save"), HTTP_GET, [this]() { - if (this->isAuthRequired()) { - if (!this->webServer->authenticate(settings.portal.login, settings.portal.password)) { - return this->webServer->send(401); - } + if (this->isAuthRequired() && !this->isValidCredentials()) { + return this->webServer->send(401); } JsonDocument doc; @@ -248,10 +244,8 @@ protected: }); this->webServer->on(F("/api/backup/restore"), HTTP_POST, [this]() { - if (this->isAuthRequired()) { - if (!this->webServer->authenticate(settings.portal.login, settings.portal.password)) { - return this->webServer->send(401); - } + if (this->isAuthRequired() && !this->isValidCredentials()) { + return this->webServer->send(401); } if (vars.states.restarting) { @@ -329,10 +323,8 @@ protected: // network this->webServer->on(F("/api/network/settings"), HTTP_GET, [this]() { - if (this->isAuthRequired()) { - if (!this->webServer->authenticate(settings.portal.login, settings.portal.password)) { - return this->webServer->send(401); - } + if (this->isAuthRequired() && !this->isValidCredentials()) { + return this->webServer->send(401); } JsonDocument doc; @@ -343,10 +335,8 @@ protected: }); this->webServer->on(F("/api/network/settings"), HTTP_POST, [this]() { - if (this->isAuthRequired()) { - if (!this->webServer->authenticate(settings.portal.login, settings.portal.password)) { - return this->webServer->send(401); - } + if (this->isAuthRequired() && !this->isValidCredentials()) { + return this->webServer->send(401); } if (vars.states.restarting) { @@ -402,11 +392,8 @@ protected: }); this->webServer->on(F("/api/network/scan"), HTTP_GET, [this]() { - if (this->isAuthRequired()) { - if (!this->webServer->authenticate(settings.portal.login, settings.portal.password)) { - this->webServer->send(401); - return; - } + if (this->isAuthRequired() && !this->isValidCredentials()) { + return this->webServer->send(401); } auto apCount = WiFi.scanComplete(); @@ -448,10 +435,8 @@ protected: // settings this->webServer->on(F("/api/settings"), HTTP_GET, [this]() { - if (this->isAuthRequired()) { - if (!this->webServer->authenticate(settings.portal.login, settings.portal.password)) { - return this->webServer->send(401); - } + if (this->isAuthRequired() && !this->isValidCredentials()) { + return this->webServer->send(401); } JsonDocument doc; @@ -462,10 +447,8 @@ protected: }); this->webServer->on(F("/api/settings"), HTTP_POST, [this]() { - if (this->isAuthRequired()) { - if (!this->webServer->authenticate(settings.portal.login, settings.portal.password)) { - return this->webServer->send(401); - } + if (this->isAuthRequired() && !this->isValidCredentials()) { + return this->webServer->send(401); } if (vars.states.restarting) { @@ -513,10 +496,8 @@ protected: // sensors list this->webServer->on(F("/api/sensors"), HTTP_GET, [this]() { - if (this->isAuthRequired()) { - if (!this->webServer->authenticate(settings.portal.login, settings.portal.password)) { - return this->webServer->send(401); - } + if (this->isAuthRequired() && !this->isValidCredentials()) { + return this->webServer->send(401); } bool detailed = false; @@ -543,10 +524,8 @@ protected: // sensor settings this->webServer->on(F("/api/sensor"), HTTP_GET, [this]() { - if (this->isAuthRequired()) { - if (!this->webServer->authenticate(settings.portal.login, settings.portal.password)) { - return this->webServer->send(401); - } + if (this->isAuthRequired() && !this->isValidCredentials()) { + return this->webServer->send(401); } if (!this->webServer->hasArg(F("id"))) { @@ -571,10 +550,8 @@ protected: }); this->webServer->on(F("/api/sensor"), HTTP_POST, [this]() { - if (this->isAuthRequired()) { - if (!this->webServer->authenticate(settings.portal.login, settings.portal.password)) { - return this->webServer->send(401); - } + if (this->isAuthRequired() && !this->isValidCredentials()) { + return this->webServer->send(401); } if (vars.states.restarting) { @@ -654,10 +631,8 @@ protected: }); this->webServer->on(F("/api/vars"), HTTP_POST, [this]() { - if (this->isAuthRequired()) { - if (!this->webServer->authenticate(settings.portal.login, settings.portal.password)) { - return this->webServer->send(401); - } + if (this->isAuthRequired() && !this->isValidCredentials()) { + return this->webServer->send(401); } const String& plain = this->webServer->arg(0); @@ -956,6 +931,10 @@ protected: return !network->isApEnabled() && settings.portal.auth && strlen(settings.portal.password); } + bool isValidCredentials() { + return this->webServer->authenticate(settings.portal.login, settings.portal.password); + } + void onCaptivePortal() { const String& uri = this->webServer->uri(); diff --git a/src_data/pages/dashboard.html b/src_data/pages/dashboard.html index 8fd7897..65d5549 100644 --- a/src_data/pages/dashboard.html +++ b/src_data/pages/dashboard.html @@ -380,13 +380,18 @@ console.log(newSettings); } - let parameters = { cache: 'no-cache' }; + let parameters = { + method: "GET", + cache: "no-cache", + credentials: "include" + }; + if (modified) { parameters.method = "POST"; parameters.body = JSON.stringify(newSettings); } - const response = await fetch('/api/settings', parameters); + const response = await fetch("/api/settings", parameters); if (!response.ok) { throw new Error('Response not valid'); } @@ -424,7 +429,11 @@ // vars try { - const response = await fetch('/api/vars', { cache: 'no-cache' }); + const response = await fetch("/api/vars", { + cache: "no-cache", + credentials: "include" + }); + if (!response.ok) { throw new Error('Response not valid'); } @@ -540,7 +549,11 @@ // sensors try { - const response = await fetch("/api/sensors?detailed=1", { cache: "no-cache" }); + const response = await fetch("/api/sensors?detailed=1", { + cache: "no-cache", + credentials: "include" + }); + if (!response.ok) { throw new Error("Response not valid"); } diff --git a/src_data/pages/index.html b/src_data/pages/index.html index 88f0585..0ea77b4 100644 --- a/src_data/pages/index.html +++ b/src_data/pages/index.html @@ -170,7 +170,11 @@ setTimeout(async function onLoadPage() { try { - const response = await fetch('/api/info', { cache: 'no-cache' }); + const response = await fetch("/api/info", { + cache: "no-cache", + credentials: "include" + }); + if (!response.ok) { throw new Error('Response not valid'); } diff --git a/src_data/pages/network.html b/src_data/pages/network.html index 88e2c66..e3b6656 100644 --- a/src_data/pages/network.html +++ b/src_data/pages/network.html @@ -199,7 +199,11 @@ }; try { - const response = await fetch('/api/network/settings', { cache: 'no-cache' }); + const response = await fetch("/api/network/settings", { + cache: "no-cache", + credentials: "include" + }); + if (!response.ok) { throw new Error('Response not valid'); } diff --git a/src_data/pages/sensors.html b/src_data/pages/sensors.html index 1626e08..ff1a988 100644 --- a/src_data/pages/sensors.html +++ b/src_data/pages/sensors.html @@ -194,7 +194,11 @@ const templateNode = container.querySelector("#template"); try { - const response = await fetch("/api/sensors", { cache: "no-cache" }); + const response = await fetch("/api/sensors", { + cache: "no-cache", + credentials: "include" + }); + if (!response.ok) { throw new Error("Response not valid"); } @@ -287,7 +291,11 @@ } try { - const response = await fetch(sensorForm.action, { cache: "no-cache" }); + const response = await fetch(sensorForm.action, { + cache: "no-cache", + credentials: "include" + }); + if (response.status != 200) { return; } diff --git a/src_data/pages/settings.html b/src_data/pages/settings.html index fe65ce9..1b22b6e 100644 --- a/src_data/pages/settings.html +++ b/src_data/pages/settings.html @@ -808,7 +808,11 @@ }; try { - const response = await fetch('/api/settings', { cache: 'no-cache' }); + const response = await fetch("/api/settings", { + cache: "no-cache", + credentials: "include" + }); + if (!response.ok) { throw new Error('Response not valid'); } diff --git a/src_data/scripts/lang.js b/src_data/scripts/lang.js index 9d2e08b..08d7616 100644 --- a/src_data/scripts/lang.js +++ b/src_data/scripts/lang.js @@ -32,7 +32,7 @@ class Lang { } if (!this.localeIsSupported(this.defaultLocale)) { - const selected = this.switcher.selectedIndex ?? 0; + const selected = this.switcher.selectedIndex ? this.switcher.selectedIndex : 0; this.defaultLocale = this.switcher.options[selected].value; } diff --git a/src_data/scripts/utils.js b/src_data/scripts/utils.js index b0bf1ef..9148849 100644 --- a/src_data/scripts/utils.js +++ b/src_data/scripts/utils.js @@ -60,10 +60,11 @@ const setupForm = (formSelector, onResultCallback = null, noCastItems = []) => { } let response = await fetch(url, { - method: 'POST', - cache: 'no-cache', + method: "POST", + cache: "no-cache", + credentials: "include", headers: { - 'Content-Type': 'application/json' + "Content-Type": "application/json" }, body: form2json(fd, noCastItems) }); @@ -218,7 +219,10 @@ const setupNetworkScanForm = (formSelector, tableSelector) => { attempts--; try { - let response = await fetch(url, { cache: 'no-cache' }); + let response = await fetch(url, { + cache: "no-cache", + credentials: "include" + }); if (response.status == 200) { await onSuccess(response); @@ -309,10 +313,11 @@ const setupRestoreBackupForm = (formSelector) => { if (data.settings != undefined) { let response = await fetch(url, { - method: 'POST', - cache: 'no-cache', + method: "POST", + cache: "no-cache", + credentials: "include", headers: { - 'Content-Type': 'application/json' + "Content-Type": "application/json" }, body: JSON.stringify({"settings": data.settings}) }); @@ -331,10 +336,11 @@ const setupRestoreBackupForm = (formSelector) => { payload["sensors"][sensorId] = data.sensors[sensorId]; const response = await fetch(url, { - method: 'POST', - cache: 'no-cache', + method: "POST", + cache: "no-cache", + credentials: "include", headers: { - 'Content-Type': 'application/json' + "Content-Type": "application/json" }, body: JSON.stringify(payload) }); @@ -348,10 +354,11 @@ const setupRestoreBackupForm = (formSelector) => { if (data.network != undefined) { let response = await fetch(url, { - method: 'POST', - cache: 'no-cache', + method: "POST", + cache: "no-cache", + credentials: "include", headers: { - 'Content-Type': 'application/json' + "Content-Type": "application/json" }, body: JSON.stringify({"network": data.network}) }); @@ -496,8 +503,9 @@ const setupUpgradeForm = (formSelector) => { try { let fd = new FormData(form); let response = await fetch(url, { - method: 'POST', - cache: 'no-cache', + method: "POST", + cache: "no-cache", + credentials: "include", body: fd });