70 lines
2.1 KiB
C++
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()
|