108 lines
3.1 KiB
C++
108 lines
3.1 KiB
C++
#include "KOReaderCredentialStore.h"
|
|
|
|
#include <Logging.h>
|
|
#include <MD5Builder.h>
|
|
#include <ObfuscationUtils.h>
|
|
|
|
namespace {
|
|
// Default sync server URL
|
|
constexpr char DEFAULT_SERVER_URL[] = "https://sync.koreader.rocks:443";
|
|
} // namespace
|
|
|
|
void KOReaderCredentialStore::toJson(JsonDocument& doc) const {
|
|
doc["username"] = getUsername();
|
|
doc["password_obf"] = obfuscation::obfuscateToBase64(getPassword());
|
|
doc["serverUrl"] = getServerUrl();
|
|
doc["matchMethod"] = static_cast<uint8_t>(getMatchMethod());
|
|
doc["sendMetadata"] = getSendMetadata();
|
|
}
|
|
|
|
bool KOReaderCredentialStore::fromJson(JsonVariantConst doc) {
|
|
std::string user = doc["username"] | "";
|
|
|
|
bool needsResave = false;
|
|
std::string pass = extractPassword(doc, needsResave);
|
|
|
|
setCredentials(user, pass);
|
|
setServerUrl(doc["serverUrl"] | "");
|
|
|
|
uint8_t method = doc["matchMethod"] | (uint8_t)0;
|
|
if (method <= static_cast<uint8_t>(DocumentMatchMethod::BINARY)) {
|
|
setMatchMethod(static_cast<DocumentMatchMethod>(method));
|
|
} else {
|
|
LOG_DBG("KRS", "Invalid matchMethod %u in JSON, resetting to FILENAME", method);
|
|
setMatchMethod(DocumentMatchMethod::FILENAME);
|
|
}
|
|
setSendMetadata(doc["sendMetadata"] | false);
|
|
|
|
if (needsResave) {
|
|
LOG_DBG("KRS", "Resaved KOReader credentials to update format");
|
|
saveToFile();
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void KOReaderCredentialStore::setCredentials(const std::string& user, const std::string& pass) {
|
|
username = user;
|
|
password = pass;
|
|
LOG_DBG("KRS", "Set credentials for user: %s", user.c_str());
|
|
}
|
|
|
|
std::string KOReaderCredentialStore::getMd5Password() const {
|
|
if (password.empty()) {
|
|
return "";
|
|
}
|
|
|
|
// Calculate MD5 hash of password using ESP32's MD5Builder
|
|
MD5Builder md5;
|
|
md5.begin();
|
|
md5.add(password.c_str());
|
|
md5.calculate();
|
|
|
|
return md5.toString().c_str();
|
|
}
|
|
|
|
bool KOReaderCredentialStore::hasCredentials() const { return !username.empty() && !password.empty(); }
|
|
|
|
void KOReaderCredentialStore::clearCredentials() {
|
|
username.clear();
|
|
password.clear();
|
|
saveToFile();
|
|
LOG_DBG("KRS", "Cleared KOReader credentials");
|
|
}
|
|
|
|
void KOReaderCredentialStore::setServerUrl(const std::string& url) {
|
|
serverUrl = url;
|
|
LOG_DBG("KRS", "Set server URL: %s", url.empty() ? "(default)" : url.c_str());
|
|
}
|
|
|
|
std::string KOReaderCredentialStore::getBaseUrl() const {
|
|
std::string url;
|
|
if (serverUrl.empty()) {
|
|
url = DEFAULT_SERVER_URL;
|
|
} else if (serverUrl.find("://") == std::string::npos) {
|
|
// Normalize URL: add http:// if no protocol specified (local servers typically don't have SSL)
|
|
url = "http://" + serverUrl;
|
|
} else {
|
|
url = serverUrl;
|
|
}
|
|
|
|
// Strip trailing slashes to avoid double-slash in API paths
|
|
while (!url.empty() && url.back() == '/') {
|
|
url.pop_back();
|
|
}
|
|
|
|
return url;
|
|
}
|
|
|
|
void KOReaderCredentialStore::setMatchMethod(DocumentMatchMethod method) {
|
|
matchMethod = method;
|
|
LOG_DBG("KRS", "Set match method: %s", method == DocumentMatchMethod::FILENAME ? "Filename" : "Binary");
|
|
}
|
|
|
|
void KOReaderCredentialStore::setSendMetadata(bool enabled) {
|
|
sendMetadata = enabled;
|
|
LOG_DBG("KRS", "Set send metadata: %s", enabled ? "true" : "false");
|
|
}
|