118 lines
3.6 KiB
C++
118 lines
3.6 KiB
C++
#include "WifiCredentialStore.h"
|
|
|
|
#include <Logging.h>
|
|
#include <ObfuscationUtils.h>
|
|
|
|
#include <algorithm>
|
|
|
|
void WifiCredentialStore::toJson(JsonDocument& doc) const {
|
|
doc["lastConnectedSsid"] = lastConnectedSsid;
|
|
|
|
JsonArray arr = doc["credentials"].to<JsonArray>();
|
|
for (const auto& cred : credentials) {
|
|
JsonObject obj = arr.add<JsonObject>();
|
|
obj["ssid"] = cred.ssid;
|
|
obj["password_obf"] = obfuscation::obfuscateToBase64(cred.password);
|
|
}
|
|
}
|
|
|
|
bool WifiCredentialStore::fromJson(JsonVariantConst doc) {
|
|
lastConnectedSsid = doc["lastConnectedSsid"] | "";
|
|
|
|
// Tolerate a missing/invalid 'credentials' key (treat as empty list); only
|
|
// a JSON parse error is fatal. A null JsonArray iterates zero times.
|
|
credentials.clear();
|
|
JsonArrayConst arr = doc["credentials"].as<JsonArrayConst>();
|
|
credentials.reserve(std::min(arr.size(), MAX_NETWORKS));
|
|
bool needsResave = false;
|
|
|
|
for (JsonObjectConst obj : arr) {
|
|
if (credentials.size() >= MAX_NETWORKS) break;
|
|
WifiCredential cred;
|
|
cred.ssid = obj["ssid"] | "";
|
|
cred.password = extractPassword(obj, needsResave);
|
|
credentials.push_back(cred);
|
|
}
|
|
|
|
LOG_DBG("WCS", "Loaded %zu WiFi credentials from file", credentials.size());
|
|
|
|
if (needsResave) {
|
|
LOG_DBG("WCS", "Resaving JSON with obfuscated passwords");
|
|
saveToFile();
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool WifiCredentialStore::addCredential(const std::string& ssid, const std::string& password) {
|
|
// Check if this SSID already exists and update it
|
|
const auto cred = find_if(credentials.begin(), credentials.end(),
|
|
[&ssid](const WifiCredential& cred) { return cred.ssid == ssid; });
|
|
if (cred != credentials.end()) {
|
|
cred->password = password;
|
|
LOG_DBG("WCS", "Updated credentials for: %s", ssid.c_str());
|
|
return saveToFile();
|
|
}
|
|
|
|
// Check if we've reached the limit
|
|
if (credentials.size() >= MAX_NETWORKS) {
|
|
LOG_DBG("WCS", "Cannot add more networks, limit of %zu reached", MAX_NETWORKS);
|
|
return false;
|
|
}
|
|
|
|
// Add new credential
|
|
credentials.push_back({ssid, password});
|
|
LOG_DBG("WCS", "Added credentials for: %s", ssid.c_str());
|
|
return saveToFile();
|
|
}
|
|
|
|
bool WifiCredentialStore::removeCredential(const std::string& ssid) {
|
|
const auto cred = find_if(credentials.begin(), credentials.end(),
|
|
[&ssid](const WifiCredential& cred) { return cred.ssid == ssid; });
|
|
if (cred != credentials.end()) {
|
|
credentials.erase(cred);
|
|
LOG_DBG("WCS", "Removed credentials for: %s", ssid.c_str());
|
|
if (ssid == lastConnectedSsid) {
|
|
clearLastConnectedSsid();
|
|
}
|
|
return saveToFile();
|
|
}
|
|
return false; // Not found
|
|
}
|
|
|
|
const WifiCredential* WifiCredentialStore::findCredential(const std::string& ssid) const {
|
|
const auto cred = find_if(credentials.begin(), credentials.end(),
|
|
[&ssid](const WifiCredential& cred) { return cred.ssid == ssid; });
|
|
|
|
if (cred != credentials.end()) {
|
|
return &*cred;
|
|
}
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
bool WifiCredentialStore::hasSavedCredential(const std::string& ssid) const { return findCredential(ssid) != nullptr; }
|
|
|
|
void WifiCredentialStore::setLastConnectedSsid(const std::string& ssid) {
|
|
if (lastConnectedSsid != ssid) {
|
|
lastConnectedSsid = ssid;
|
|
saveToFile();
|
|
}
|
|
}
|
|
|
|
const std::string& WifiCredentialStore::getLastConnectedSsid() const { return lastConnectedSsid; }
|
|
|
|
void WifiCredentialStore::clearLastConnectedSsid() {
|
|
if (!lastConnectedSsid.empty()) {
|
|
lastConnectedSsid.clear();
|
|
saveToFile();
|
|
}
|
|
}
|
|
|
|
void WifiCredentialStore::clearAll() {
|
|
credentials.clear();
|
|
lastConnectedSsid.clear();
|
|
saveToFile();
|
|
LOG_DBG("WCS", "Cleared all WiFi credentials");
|
|
}
|