#pragma once #include #include #include #include struct OpdsServer { std::string name; std::string url; std::string username; std::string password; // Plaintext in memory; obfuscated with hardware key on disk }; /** * Singleton class for storing OPDS server configurations on the SD card. * Passwords are XOR-obfuscated with the device's unique hardware MAC address * and base64-encoded before writing to JSON. */ class OpdsServerStore : public PersistableStore { private: std::vector servers; static constexpr size_t MAX_SERVERS = 8; OpdsServerStore() = default; friend class PersistableStore; public: static const char* getFilePath() { return "/.crosspoint/opds.json"; } void toJson(JsonDocument& doc) const; bool fromJson(JsonVariantConst doc); bool addServer(const OpdsServer& server); bool updateServer(size_t index, const OpdsServer& server); bool removeServer(size_t index); const std::vector& getServers() const { return servers; } const OpdsServer* getServer(size_t index) const; size_t getCount() const { return servers.size(); } bool hasServers() const { return !servers.empty(); } }; #define OPDS_STORE OpdsServerStore::getInstance()