diff --git a/README.md b/README.md index bd9c038..db13ba9 100644 --- a/README.md +++ b/README.md @@ -14,15 +14,22 @@ You can add any new filter you want by implementing the `NoteFilter` trait and r The `pipeline` config specifies the order in which filters are run. When the first `reject` or `shadowReject` action is hit, then the pipeline stops and returns the rejection error. ```toml -pipeline = ["protected_events", "whitelist", "ratelimit"] +pipeline = ["protected_events", "kinds", "whitelist", "ratelimit"] [filters.ratelimit] posts_per_minute = 8 whitelist = ["127.0.0.1"] [filters.whitelist] -pubkeys = ["32e1827635450ebb3c5a7d12c1f8e7b2b514439ac10a67eef3d9fd9c5c68e245"] -ips = ["127.0.0.1", "127.0.0.2"] +pubkeys = ["16c21558762108afc34e4ff19e4ed51d9a48f79e0c34531efc423d21ab435e93"] +ips = ["127.0.0.1"] + +[filters.kinds] +kinds = [30065, 1064] + +[filters.kinds.messages] +30065 = "blocked: files on nostr is dumb" +1064 = "blocked: files on nostr is dumb" [filters.protected_events] ``` @@ -57,6 +64,27 @@ The whitelist filter only allows notes to pass if it matches a particular pubkey Either criteria can match +### Kinds + +* name: `kinds` + +A filter that blacklists certain kinds + +- `kinds`: a list of kind integers to block + +- `kinds.messages` *optional*: a map of kinds to message to deliver when the kind is blocked + +Example: + +```toml +[filters.kinds] +kinds = [30065, 1064] + +[filters.kinds.messages] +30065 = "blocked: files on nostr is dumb" +1064 = "blocked: files on nostr is dumb" +``` + ### Protected Events See [nip70] diff --git a/noteguard.toml b/noteguard.toml index efdc3d2..6fa9fb8 100644 --- a/noteguard.toml +++ b/noteguard.toml @@ -1,5 +1,5 @@ -pipeline = ["protected_events", "whitelist", "ratelimit"] +pipeline = ["protected_events", "kinds", "whitelist", "ratelimit"] [filters.ratelimit] posts_per_minute = 8 @@ -9,4 +9,13 @@ whitelist = ["127.0.0.1"] pubkeys = ["16c21558762108afc34e4ff19e4ed51d9a48f79e0c34531efc423d21ab435e93"] ips = ["127.0.0.1"] +[filters.kinds] +kinds = [30065, 1064, 34550, 4550] + +[filters.kinds.messages] +30065 = "blocked: files on nostr is dumb" +1064 = "blocked: files on nostr is dumb" +34550 = "blocked: please use a dedicated relay for moderated communities" +4550 = "blocked: please use a dedicated relay for moderated communities" + [filters.protected_events] diff --git a/src/filters/kinds.rs b/src/filters/kinds.rs new file mode 100644 index 0000000..d1a1db1 --- /dev/null +++ b/src/filters/kinds.rs @@ -0,0 +1,29 @@ +use crate::{Action, InputMessage, NoteFilter, OutputMessage}; +use serde::Deserialize; +use std::collections::HashMap; + +#[derive(Deserialize, Default)] +pub struct Kinds { + kinds: Vec, + messages: Option>, +} + +impl NoteFilter for Kinds { + fn filter_note(&mut self, input: &InputMessage) -> OutputMessage { + let kind = input.event.kind; + if self.kinds.contains(&kind) { + let msg = self + .messages + .as_ref() + .and_then(|msgs| msgs.get(&kind.to_string()).cloned()) + .unwrap_or_else(|| "blocked: note kind is not allowed here".to_string()); + OutputMessage::new(input.event.id.clone(), Action::Reject, Some(msg)) + } else { + OutputMessage::new(input.event.id.clone(), Action::Accept, None) + } + } + + fn name(&self) -> &'static str { + "kinds" + } +} diff --git a/src/filters/mod.rs b/src/filters/mod.rs index b29e8a4..dc9857c 100644 --- a/src/filters/mod.rs +++ b/src/filters/mod.rs @@ -1,7 +1,9 @@ +mod kinds; mod protected_events; mod ratelimit; mod whitelist; +pub use kinds::Kinds; pub use protected_events::ProtectedEvents; pub use ratelimit::RateLimit; pub use whitelist::Whitelist; diff --git a/src/main.rs b/src/main.rs index 9ffecb6..4aa4e12 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,4 @@ -use noteguard::filters::{ProtectedEvents, RateLimit, Whitelist}; +use noteguard::filters::{Kinds, ProtectedEvents, RateLimit, Whitelist}; use noteguard::{Action, InputMessage, NoteFilter, OutputMessage}; use serde::de::DeserializeOwned; use serde::Deserialize; @@ -43,6 +43,7 @@ impl Noteguard { self.register_filter::(); self.register_filter::(); self.register_filter::(); + self.register_filter::(); } /// Run the loaded filters. You must call `load_config` before calling this, otherwise