mirror of
https://github.com/daveallie/crosspoint-reader.git
synced 2026-02-05 23:27:38 +03:00
support for 3rd party server urls
This commit is contained in:
parent
d75d911c1b
commit
ae34fc76e1
@ -15,6 +15,9 @@ constexpr uint8_t KOREADER_FILE_VERSION = 1;
|
|||||||
// KOReader credentials file path
|
// KOReader credentials file path
|
||||||
constexpr char KOREADER_FILE[] = "/.crosspoint/koreader.bin";
|
constexpr char KOREADER_FILE[] = "/.crosspoint/koreader.bin";
|
||||||
|
|
||||||
|
// Default sync server URL
|
||||||
|
constexpr char DEFAULT_SERVER_URL[] = "https://sync.koreader.rocks:443";
|
||||||
|
|
||||||
// Obfuscation key - "KOReader" in ASCII
|
// Obfuscation key - "KOReader" in ASCII
|
||||||
// This is NOT cryptographic security, just prevents casual file reading
|
// This is NOT cryptographic security, just prevents casual file reading
|
||||||
constexpr uint8_t OBFUSCATION_KEY[] = {0x4B, 0x4F, 0x52, 0x65, 0x61, 0x64, 0x65, 0x72};
|
constexpr uint8_t OBFUSCATION_KEY[] = {0x4B, 0x4F, 0x52, 0x65, 0x61, 0x64, 0x65, 0x72};
|
||||||
@ -48,6 +51,9 @@ bool KOReaderCredentialStore::saveToFile() const {
|
|||||||
obfuscate(obfuscatedPwd);
|
obfuscate(obfuscatedPwd);
|
||||||
serialization::writeString(file, obfuscatedPwd);
|
serialization::writeString(file, obfuscatedPwd);
|
||||||
|
|
||||||
|
// Write server URL
|
||||||
|
serialization::writeString(file, serverUrl);
|
||||||
|
|
||||||
file.close();
|
file.close();
|
||||||
Serial.printf("[%lu] [KRS] Saved KOReader credentials to file\n", millis());
|
Serial.printf("[%lu] [KRS] Saved KOReader credentials to file\n", millis());
|
||||||
return true;
|
return true;
|
||||||
@ -70,11 +76,26 @@ bool KOReaderCredentialStore::loadFromFile() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Read username
|
// Read username
|
||||||
serialization::readString(file, username);
|
if (file.available()) {
|
||||||
|
serialization::readString(file, username);
|
||||||
|
} else {
|
||||||
|
username.clear();
|
||||||
|
}
|
||||||
|
|
||||||
// Read and deobfuscate password
|
// Read and deobfuscate password
|
||||||
serialization::readString(file, password);
|
if (file.available()) {
|
||||||
obfuscate(password); // XOR is symmetric, so same function deobfuscates
|
serialization::readString(file, password);
|
||||||
|
obfuscate(password); // XOR is symmetric, so same function deobfuscates
|
||||||
|
} else {
|
||||||
|
password.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read server URL
|
||||||
|
if (file.available()) {
|
||||||
|
serialization::readString(file, serverUrl);
|
||||||
|
} else {
|
||||||
|
serverUrl.clear();
|
||||||
|
}
|
||||||
|
|
||||||
file.close();
|
file.close();
|
||||||
Serial.printf("[%lu] [KRS] Loaded KOReader credentials for user: %s\n", millis(), username.c_str());
|
Serial.printf("[%lu] [KRS] Loaded KOReader credentials for user: %s\n", millis(), username.c_str());
|
||||||
@ -109,3 +130,21 @@ void KOReaderCredentialStore::clearCredentials() {
|
|||||||
saveToFile();
|
saveToFile();
|
||||||
Serial.printf("[%lu] [KRS] Cleared KOReader credentials\n", millis());
|
Serial.printf("[%lu] [KRS] Cleared KOReader credentials\n", millis());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void KOReaderCredentialStore::setServerUrl(const std::string& url) {
|
||||||
|
serverUrl = url;
|
||||||
|
Serial.printf("[%lu] [KRS] Set server URL: %s\n", millis(), url.empty() ? "(default)" : url.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string KOReaderCredentialStore::getBaseUrl() const {
|
||||||
|
if (serverUrl.empty()) {
|
||||||
|
return DEFAULT_SERVER_URL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Normalize URL: add https:// if no protocol specified
|
||||||
|
if (serverUrl.find("://") == std::string::npos) {
|
||||||
|
return "https://" + serverUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
return serverUrl;
|
||||||
|
}
|
||||||
|
|||||||
@ -11,6 +11,7 @@ class KOReaderCredentialStore {
|
|||||||
static KOReaderCredentialStore instance;
|
static KOReaderCredentialStore instance;
|
||||||
std::string username;
|
std::string username;
|
||||||
std::string password;
|
std::string password;
|
||||||
|
std::string serverUrl; // Custom sync server URL (empty = default)
|
||||||
|
|
||||||
// Private constructor for singleton
|
// Private constructor for singleton
|
||||||
KOReaderCredentialStore() = default;
|
KOReaderCredentialStore() = default;
|
||||||
@ -43,6 +44,13 @@ class KOReaderCredentialStore {
|
|||||||
|
|
||||||
// Clear credentials
|
// Clear credentials
|
||||||
void clearCredentials();
|
void clearCredentials();
|
||||||
|
|
||||||
|
// Server URL management
|
||||||
|
void setServerUrl(const std::string& url);
|
||||||
|
const std::string& getServerUrl() const { return serverUrl; }
|
||||||
|
|
||||||
|
// Get base URL for API calls (with https:// normalization, falls back to default)
|
||||||
|
std::string getBaseUrl() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Helper macro to access credential store
|
// Helper macro to access credential store
|
||||||
|
|||||||
@ -10,9 +10,6 @@
|
|||||||
#include "KOReaderCredentialStore.h"
|
#include "KOReaderCredentialStore.h"
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
// Base URL for KOReader sync server
|
|
||||||
constexpr char BASE_URL[] = "https://sync.koreader.rocks:443";
|
|
||||||
|
|
||||||
// Device identifier for CrossPoint reader
|
// Device identifier for CrossPoint reader
|
||||||
constexpr char DEVICE_NAME[] = "CrossPoint";
|
constexpr char DEVICE_NAME[] = "CrossPoint";
|
||||||
constexpr char DEVICE_ID[] = "crosspoint-reader";
|
constexpr char DEVICE_ID[] = "crosspoint-reader";
|
||||||
@ -34,7 +31,7 @@ KOReaderSyncClient::Error KOReaderSyncClient::authenticate() {
|
|||||||
client->setInsecure();
|
client->setInsecure();
|
||||||
HTTPClient http;
|
HTTPClient http;
|
||||||
|
|
||||||
std::string url = std::string(BASE_URL) + "/users/auth";
|
std::string url = KOREADER_STORE.getBaseUrl() + "/users/auth";
|
||||||
Serial.printf("[%lu] [KOSync] Authenticating: %s\n", millis(), url.c_str());
|
Serial.printf("[%lu] [KOSync] Authenticating: %s\n", millis(), url.c_str());
|
||||||
|
|
||||||
http.begin(*client, url.c_str());
|
http.begin(*client, url.c_str());
|
||||||
@ -66,7 +63,7 @@ KOReaderSyncClient::Error KOReaderSyncClient::getProgress(const std::string& doc
|
|||||||
client->setInsecure();
|
client->setInsecure();
|
||||||
HTTPClient http;
|
HTTPClient http;
|
||||||
|
|
||||||
std::string url = std::string(BASE_URL) + "/syncs/progress/" + documentHash;
|
std::string url = KOREADER_STORE.getBaseUrl() + "/syncs/progress/" + documentHash;
|
||||||
Serial.printf("[%lu] [KOSync] Getting progress: %s\n", millis(), url.c_str());
|
Serial.printf("[%lu] [KOSync] Getting progress: %s\n", millis(), url.c_str());
|
||||||
|
|
||||||
http.begin(*client, url.c_str());
|
http.begin(*client, url.c_str());
|
||||||
@ -121,7 +118,7 @@ KOReaderSyncClient::Error KOReaderSyncClient::updateProgress(const KOReaderProgr
|
|||||||
client->setInsecure();
|
client->setInsecure();
|
||||||
HTTPClient http;
|
HTTPClient http;
|
||||||
|
|
||||||
std::string url = std::string(BASE_URL) + "/syncs/progress";
|
std::string url = KOREADER_STORE.getBaseUrl() + "/syncs/progress";
|
||||||
Serial.printf("[%lu] [KOSync] Updating progress: %s\n", millis(), url.c_str());
|
Serial.printf("[%lu] [KOSync] Updating progress: %s\n", millis(), url.c_str());
|
||||||
|
|
||||||
http.begin(*client, url.c_str());
|
http.begin(*client, url.c_str());
|
||||||
|
|||||||
@ -11,8 +11,8 @@
|
|||||||
#include "fontIds.h"
|
#include "fontIds.h"
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
constexpr int MENU_ITEMS = 3;
|
constexpr int MENU_ITEMS = 4;
|
||||||
const char* menuNames[MENU_ITEMS] = {"Username", "Password", "Authenticate"};
|
const char* menuNames[MENU_ITEMS] = {"Username", "Password", "Sync Server URL", "Authenticate"};
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
void KOReaderSettingsActivity::taskTrampoline(void* param) {
|
void KOReaderSettingsActivity::taskTrampoline(void* param) {
|
||||||
@ -112,6 +112,23 @@ void KOReaderSettingsActivity::handleSelection() {
|
|||||||
updateRequired = true;
|
updateRequired = true;
|
||||||
}));
|
}));
|
||||||
} else if (selectedIndex == 2) {
|
} else if (selectedIndex == 2) {
|
||||||
|
// Sync Server URL
|
||||||
|
exitActivity();
|
||||||
|
enterNewActivity(new KeyboardEntryActivity(
|
||||||
|
renderer, mappedInput, "Sync Server URL", KOREADER_STORE.getServerUrl(), 10,
|
||||||
|
128, // maxLength - URLs can be long
|
||||||
|
false, // not password
|
||||||
|
[this](const std::string& url) {
|
||||||
|
KOREADER_STORE.setServerUrl(url);
|
||||||
|
KOREADER_STORE.saveToFile();
|
||||||
|
exitActivity();
|
||||||
|
updateRequired = true;
|
||||||
|
},
|
||||||
|
[this]() {
|
||||||
|
exitActivity();
|
||||||
|
updateRequired = true;
|
||||||
|
}));
|
||||||
|
} else if (selectedIndex == 3) {
|
||||||
// Authenticate
|
// Authenticate
|
||||||
if (!KOREADER_STORE.hasCredentials()) {
|
if (!KOREADER_STORE.hasCredentials()) {
|
||||||
// Can't authenticate without credentials - just show message briefly
|
// Can't authenticate without credentials - just show message briefly
|
||||||
@ -158,13 +175,15 @@ void KOReaderSettingsActivity::render() {
|
|||||||
|
|
||||||
renderer.drawText(UI_10_FONT_ID, 20, settingY, menuNames[i], !isSelected);
|
renderer.drawText(UI_10_FONT_ID, 20, settingY, menuNames[i], !isSelected);
|
||||||
|
|
||||||
// Draw status for username/password
|
// Draw status for each item
|
||||||
const char* status = "";
|
const char* status = "";
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
status = KOREADER_STORE.getUsername().empty() ? "[Not Set]" : "[Set]";
|
status = KOREADER_STORE.getUsername().empty() ? "[Not Set]" : "[Set]";
|
||||||
} else if (i == 1) {
|
} else if (i == 1) {
|
||||||
status = KOREADER_STORE.getPassword().empty() ? "[Not Set]" : "[Set]";
|
status = KOREADER_STORE.getPassword().empty() ? "[Not Set]" : "[Set]";
|
||||||
} else if (i == 2) {
|
} else if (i == 2) {
|
||||||
|
status = KOREADER_STORE.getServerUrl().empty() ? "[Not Set]" : "[Set]";
|
||||||
|
} else if (i == 3) {
|
||||||
status = KOREADER_STORE.hasCredentials() ? "" : "[Set credentials first]";
|
status = KOREADER_STORE.hasCredentials() ? "" : "[Set credentials first]";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user