#pragma once #include #include #include #include // Document matching method for KOReader sync enum class DocumentMatchMethod : uint8_t { FILENAME = 0, // Match by filename (simpler, works across different file sources) BINARY = 1, // Match by partial MD5 of file content (more accurate, but files must be identical) }; // How manual "Sync Progress" resolves differences after fetching remote progress. enum class KOReaderSyncBehavior : uint8_t { ASK_EVERY_TIME = 0, // Preserve legacy behavior: always show Apply/Upload choices. SMART = 1, // Auto-resolve simple cases using furthest progress. }; /** * Singleton class for storing KOReader sync credentials on the SD card. * Passwords are XOR-obfuscated with the device's unique hardware MAC address * and base64-encoded before writing to JSON (not cryptographically secure, * but prevents casual reading and ties credentials to the specific device). */ class KOReaderCredentialStore : public PersistableStore { private: std::string username; std::string password; std::string serverUrl; // Custom sync server URL (empty = default) DocumentMatchMethod matchMethod = DocumentMatchMethod::FILENAME; // Default to filename for compatibility bool sendMetadata = false; // Send document metadata with progress sync KOReaderSyncBehavior syncBehavior = KOReaderSyncBehavior::SMART; // Private constructor for singleton KOReaderCredentialStore() = default; ~KOReaderCredentialStore() = default; friend class PersistableStore; public: static const char* getFilePath() { return "/.crosspoint/koreader.json"; } void toJson(JsonDocument& doc) const; bool fromJson(JsonVariantConst doc); // Credential management void setCredentials(const std::string& user, const std::string& pass); const std::string& getUsername() const { return username; } const std::string& getPassword() const { return password; } // Get MD5 hash of password for API authentication std::string getMd5Password() const; // Check if credentials are set bool hasCredentials() const; // Clear credentials 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 http:// normalization if no protocol, falls back to default) std::string getBaseUrl() const; // Document matching method void setMatchMethod(DocumentMatchMethod method); DocumentMatchMethod getMatchMethod() const { return matchMethod; } // Send metadata setting void setSendMetadata(bool enabled); bool getSendMetadata() const { return sendMetadata; } // Sync behavior void setSyncBehavior(KOReaderSyncBehavior behavior); KOReaderSyncBehavior getSyncBehavior() const { return syncBehavior; } }; // Helper macro to access credential store #define KOREADER_STORE KOReaderCredentialStore::getInstance()