diff options
author | Michael Jurkoic <mjjurkoic@gmail.com> | 2024-03-12 09:32:25 -0500 |
---|---|---|
committer | Michael Jurkoic <mjjurkoic@gmail.com> | 2024-03-12 09:32:25 -0500 |
commit | 6134935fd0c7adfb097824ea9e57207e3f97423b (patch) | |
tree | 076af452ca4214e898b29a0cab48fa005a280890 | |
parent | a57db2270f1a841325c47d5113befbb5ca532952 (diff) |
Add validation on Event serialization
-rw-r--r-- | include/nostr.hpp | 22 | ||||
-rw-r--r-- | src/event.cpp | 52 |
2 files changed, 68 insertions, 6 deletions
diff --git a/include/nostr.hpp b/include/nostr.hpp index 47b56f9..ec8d1a8 100644 --- a/include/nostr.hpp +++ b/include/nostr.hpp @@ -27,14 +27,32 @@ struct Event { std::string id; ///< SHA-256 hash of the event data. std::string pubkey; ///< Public key of the event creator. - std::string created_at; ///< Unix timestamp of the event creation. + std::time_t createdAt; ///< Unix timestamp of the event creation. int kind; ///< Event kind. std::vector<std::vector<std::string>> tags; ///< Arbitrary event metadata. std::string content; ///< Event content. std::string sig; ///< Event signature created with the private key of the event creator. - nlohmann::json serialize() const; + /** + * @brief Serializes the event to a JSON object. + * @returns A stringified JSON object representing the event. + * @throws `std::invalid_argument` if the event object is invalid. + */ + std::string serialize(); + + /** + * @brief Deserializes the event from a JSON string. + * @param jsonString A stringified JSON object representing the event. + */ void deserialize(std::string jsonString); + +private: + /** + * @brief Validates the event. + * @throws `std::invalid_argument` if the event object is invalid. + * @remark The `createdAt` field defaults to the present if it is not already set. + */ + void validate(); }; class NostrService diff --git a/src/event.cpp b/src/event.cpp index 0e4e159..6a179fa 100644 --- a/src/event.cpp +++ b/src/event.cpp @@ -1,20 +1,31 @@ +#include <ctime> #include <string> -#include <vector> #include <nlohmann/json.hpp> #include "nostr.hpp" using nlohmann::json; +using std::invalid_argument; using std::string; +using std::time; namespace nostr { -json Event::serialize() const +string Event::serialize() { + try + { + this->validate(); + } + catch (const invalid_argument& e) + { + throw e; + } + json j = { {"id", this->id}, {"pubkey", this->pubkey}, - {"created_at", this->created_at}, + {"created_at", this->createdAt}, {"kind", this->kind}, {"tags", this->tags}, {"content", this->content}, @@ -28,10 +39,43 @@ void Event::deserialize(string jsonString) json j = json::parse(jsonString); this->id = j["id"]; this->pubkey = j["pubkey"]; - this->created_at = j["created_at"]; + this->createdAt = j["created_at"]; this->kind = j["kind"]; this->tags = j["tags"]; this->content = j["content"]; this->sig = j["sig"]; }; + +void Event::validate() +{ + bool hasId = this->id.length() > 0; + if (!hasId) + { + throw std::invalid_argument("Event::validate: The event id is required."); + } + + bool hasPubkey = this->pubkey.length() > 0; + if (!hasPubkey) + { + throw std::invalid_argument("Event::validate: The pubkey of the event author is required."); + } + + bool hasCreatedAt = this->createdAt > 0; + if (!hasCreatedAt) + { + this->createdAt = time(nullptr); + } + + bool hasKind = this->kind >= 0 && this->kind < 40000; + if (!hasKind) + { + throw std::invalid_argument("Event::validate: A valid event kind is required."); + } + + bool hasSig = this->sig.length() > 0; + if (!hasSig) + { + throw std::invalid_argument("Event::validate: The event must be signed."); + } +}; } // namespace nostr |