aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLibravatar Michael Jurkoic <mjjurkoic@gmail.com>2024-03-12 09:32:25 -0500
committerLibravatar Michael Jurkoic <mjjurkoic@gmail.com>2024-03-12 09:32:25 -0500
commit6134935fd0c7adfb097824ea9e57207e3f97423b (patch)
tree076af452ca4214e898b29a0cab48fa005a280890
parenta57db2270f1a841325c47d5113befbb5ca532952 (diff)
Add validation on Event serialization
-rw-r--r--include/nostr.hpp22
-rw-r--r--src/event.cpp52
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