Files
Crosspoint/src/OpdsServerStore.h
T
2026-04-23 17:08:08 +02:00

70 lines
2.1 KiB
C++

#pragma once
#include <optional>
#include <string>
#include <vector>
struct OpdsServer {
std::string name;
std::string url;
std::string username;
std::string password; // Plaintext in memory; obfuscated with hardware key on disk
};
class OpdsServerStore;
namespace JsonSettingsIO {
bool saveOpds(const OpdsServerStore& store, const char* path);
bool loadOpds(OpdsServerStore& store, const char* json, bool* needsResave);
} // namespace JsonSettingsIO
namespace OpdsServerValidation {
std::optional<std::string> normalizeUrl(const std::string& url);
}
/**
* 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 {
private:
static OpdsServerStore instance;
std::vector<OpdsServer> servers;
OpdsServerStore() = default;
friend bool JsonSettingsIO::saveOpds(const OpdsServerStore&, const char*);
friend bool JsonSettingsIO::loadOpds(OpdsServerStore&, const char*, bool*);
public:
static constexpr size_t MAX_SERVERS = 8;
static constexpr size_t MAX_NAME_LENGTH = 63;
static constexpr size_t MAX_URL_LENGTH = 127;
static constexpr size_t MAX_USERNAME_LENGTH = 63;
static constexpr size_t MAX_PASSWORD_LENGTH = 63;
OpdsServerStore(const OpdsServerStore&) = delete;
OpdsServerStore& operator=(const OpdsServerStore&) = delete;
static OpdsServerStore& getInstance() { return instance; }
bool saveToFile() const;
bool loadFromFile();
std::optional<size_t> addServer(const OpdsServer& server);
bool updateServer(size_t index, const OpdsServer& server);
bool removeServer(size_t index);
const std::vector<OpdsServer>& getServers() const { return servers; }
const OpdsServer* getServer(size_t index) const;
size_t getCount() const { return servers.size(); }
bool hasServers() const { return !servers.empty(); }
/**
* Migrate from legacy single-server settings in CrossPointSettings.
* Called once during first load if no opds.json exists.
*/
bool migrateFromSettings();
};
#define OPDS_STORE OpdsServerStore::getInstance()