More work on webserver
This commit is contained in:
@@ -220,6 +220,13 @@ void Config::dump() {
|
||||
LOGI(TAG, "====================================");
|
||||
}
|
||||
|
||||
void Config::clear() {
|
||||
LOGI(TAG, "Clearing NVS volume: %s", PREF_NAME);
|
||||
prefs.begin(PREF_NAME, false);
|
||||
prefs.clear();
|
||||
prefs.end();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T Config::get(const char* key) const {
|
||||
return std::get<T>(values.at(key));
|
||||
|
||||
@@ -623,16 +623,18 @@ void send_sensor_brightness(uint16_t value) {
|
||||
// device instance 8bits
|
||||
// brightness 0-100%, resolution 0.1% 16bits
|
||||
// 3 bytes reserved
|
||||
uint16_t n2kvalue = value * 1000UL / 4095; // 0..100%, resolution 0.1
|
||||
tN2kMsg N2kMsg;
|
||||
N2kMsg.SetPGN(65280); // proprietary PGN
|
||||
N2kMsg.Priority = 6;
|
||||
// 11bits manuf.-code, 2bits reserved (1), 3bits industry group
|
||||
N2kMsg.Add2ByteUInt((N2K_MANUFACTURERCODE & 0x7FF) | (0x03 << 11) | ((N2K_INDUSTRYGROUP & 0x7) << 13));
|
||||
N2kMsg.AddByte(0); // instance not yet used now
|
||||
N2kMsg.Add2ByteUInt(value * 1000UL / 4095); // resolution 0.1
|
||||
N2kMsg.Add2ByteUInt(n2kvalue);
|
||||
N2kMsg.AddByte(0xFF); //reserved bytes
|
||||
N2kMsg.AddByte(0xFF);
|
||||
N2kMsg.AddByte(0xFF);
|
||||
LOGI(TAG, "Sending LDR value=%d (%d)", n2kvalue, value);
|
||||
NMEA2000.SendMsg(N2kMsg);
|
||||
}
|
||||
|
||||
@@ -772,10 +774,9 @@ void loop() {
|
||||
send_sensor_temphum(temp + 273.15, hum);
|
||||
|
||||
#ifdef HARDWARE_V2
|
||||
// Send brightness to NMEA2000 (proprietary)
|
||||
int ldrval = analogRead(LDR);
|
||||
LOGI(TAG, "LDR value =%d", ldrval);
|
||||
// TODO send brightness to NMEA2000
|
||||
//send_sensor_brightness(ldrval);
|
||||
send_sensor_brightness(ldrval);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
@@ -76,6 +76,18 @@ String uptime_with_unit() {
|
||||
return String(uptime) + " " + uptime_unit;
|
||||
}
|
||||
|
||||
bool check_pass(String hash) {
|
||||
if (! config.getBool("useAdminPass")) {
|
||||
return true;
|
||||
}
|
||||
char salt[9]; // use to easy get upper case hex
|
||||
sprintf(salt, "%08X", apiToken + (millis()/1000UL & ~0x7UL));
|
||||
String passhash = get_sha256(String(salt) + config.getString("adminPassword"));
|
||||
LOGD(TAG, "check hash: %s", hash.c_str());
|
||||
LOGD(TAG, "check against: %s", passhash.c_str());
|
||||
return hash == passhash;
|
||||
}
|
||||
|
||||
void webserver_init() {
|
||||
|
||||
// Route for root / web page
|
||||
@@ -103,16 +115,23 @@ void webserver_init() {
|
||||
|
||||
server.on("/api/checkpass", HTTP_GET, [](AsyncWebServerRequest *request) {
|
||||
// hash has to be in sha256 format
|
||||
AsyncResponseStream *response = request->beginResponseStream("application/json");
|
||||
LOGD(TAG, "checkpass called");
|
||||
String hash = request->arg("hash");
|
||||
StaticJsonDocument<100> doc;
|
||||
String passhash = get_sha256(config.getString("adminPassword"));
|
||||
LOGD(TAG, "check hash: %s", hash.c_str());
|
||||
LOGD(TAG, "check against: %s", passhash.c_str());
|
||||
doc["status"] = hash == passhash ? "OK" : "FAILED";
|
||||
String out;
|
||||
serializeJson(doc, out);
|
||||
request->send(200, "application/json", out);
|
||||
//StaticJsonDocument<100> doc;
|
||||
//char salt[9];
|
||||
//sprintf(salt, "%08X", apiToken + (millis()/1000UL & ~0x7UL));
|
||||
//String passhash = get_sha256(String(salt) + config.getString("adminPassword"));
|
||||
//LOGD(TAG, "check hash: %s", hash.c_str());
|
||||
//LOGD(TAG, "check against: %s", passhash.c_str());
|
||||
//doc["status"] = check_pass(hash) ? "OK" : "FAILED";
|
||||
//String out;
|
||||
//serializeJson(doc, out);
|
||||
//request->send(200, "application/json", out);
|
||||
response->print(R"({"status":)");
|
||||
response->print(check_pass(hash) ? R"("OK")" : R"("FAILED")");
|
||||
response->print("}");
|
||||
request->send(response);
|
||||
});
|
||||
|
||||
server.on("/api/config", HTTP_GET, [](AsyncWebServerRequest *request) {
|
||||
@@ -125,12 +144,10 @@ void webserver_init() {
|
||||
doc["instDesc2"] = config.getString("instDesc2");
|
||||
doc["logLevel"] = loglevel;
|
||||
doc["version"] = VERSION;
|
||||
doc["AdminPassword"] = "********";
|
||||
doc["useAdminPass"] = config.getBool("useAdminPass") ? "true" : "false";
|
||||
doc["apEnable"] = config.getBool("apEnable") ? "true" : "false";
|
||||
doc["apIp"] = config.getString("apIp");
|
||||
doc["apMask"] = config.getString("apMask");
|
||||
doc["apPassword"] = "********";
|
||||
doc["stopApTime"] = config.getShort("stopApTime");
|
||||
doc["apHidden"] = config.getBool("apHidden") ? "true" : "false";
|
||||
doc["cpuSpeed"] = config.getShort("cpuSpeed");
|
||||
@@ -160,31 +177,55 @@ void webserver_init() {
|
||||
doc["n2kDestC"] = config.getString("n2kDestC");
|
||||
doc["switchBankC"] = config.getByte("switchBankC");
|
||||
doc["envInterval"] = config.getShort("envInterval");
|
||||
|
||||
// TODO needed? Perhaps because entry fields are created by this list
|
||||
doc["AdminPassword"] = "********";
|
||||
doc["apPassword"] = "********";
|
||||
|
||||
String out;
|
||||
serializeJson(doc, out);
|
||||
request->send(200, "application/json", out);
|
||||
});
|
||||
|
||||
server.on("/api/reset", HTTP_GET, [](AsyncWebServerRequest *request) {
|
||||
LOGD(TAG, "reset called");
|
||||
StaticJsonDocument<100> doc;
|
||||
AsyncResponseStream *response = request->beginResponseStream("application/json");
|
||||
String hash = request->arg("hash");
|
||||
response->print(R"([{"status":)");
|
||||
if (check_pass(hash)) {
|
||||
LOGD(TAG, "reset called");
|
||||
response->print(R"("OK")");
|
||||
response->print("}]");
|
||||
ledcWrite(LEDC_RGBLED_B, 0); // blue config light off
|
||||
led_blink(LEDC_RGBLED_G, 3, 4095, 500);
|
||||
esp_rom_uart_tx_wait_idle(0);
|
||||
ESP.restart();
|
||||
|
||||
}
|
||||
LOGD(TAG, "reset failed: wrong password");
|
||||
response->print(R"("FAILED")");
|
||||
response->print("}]");
|
||||
|
||||
/*StaticJsonDocument<100> doc;
|
||||
doc["status"] = "OK";
|
||||
String out;
|
||||
serializeJson(doc, out);
|
||||
request->send(200, "application/json", out);
|
||||
ledcWrite(LEDC_RGBLED_B, 0); // blue config light off
|
||||
led_blink(LEDC_RGBLED_G, 3, 4095, 500);
|
||||
esp_rom_uart_tx_wait_idle(0);
|
||||
ESP.restart();
|
||||
request->send(200, "application/json", out); */
|
||||
});
|
||||
|
||||
server.on("/api/resetconfig", HTTP_GET, [](AsyncWebServerRequest *request) {
|
||||
AsyncResponseStream *response = request->beginResponseStream("application/json");
|
||||
String hash = request->arg("hash");
|
||||
if (check_pass(hash)) {
|
||||
LOGD(TAG, "resetconfig: checkpass successful");
|
||||
} else {
|
||||
LOGD(TAG, "resetconfig: checkpass failed");
|
||||
}
|
||||
LOGD(TAG, "resetconfig called");
|
||||
StaticJsonDocument<100> doc;
|
||||
doc["status"] = "FAILED";
|
||||
String out;
|
||||
serializeJson(doc, out);
|
||||
request->send(200, "application/json", out);
|
||||
// config.clear();
|
||||
response->print("{");
|
||||
response->print(R"DELIM({"status": "FAILED"})DELIM");
|
||||
response->print("}");
|
||||
request->send(response);
|
||||
});
|
||||
|
||||
server.on("/api/status", HTTP_GET, [](AsyncWebServerRequest *request) {
|
||||
@@ -229,6 +270,10 @@ void webserver_init() {
|
||||
sprintf(salt, "%08X", apiToken + (millis()/1000UL & ~0x7UL));
|
||||
doc["salt"] = salt;
|
||||
|
||||
// security warnings
|
||||
doc["warnAdminPass"] = config.getString("AdminPassword") == ADMIN_PASS ? "true" : "false";
|
||||
doc["warnApPass"] = config.getString("apPassword") == WIFI_PASS ? "true" : "false";
|
||||
|
||||
doc["status"] = "OK";
|
||||
String out;
|
||||
serializeJson(doc, out);
|
||||
|
||||
Reference in New Issue
Block a user