mirror of
https://github.com/scsibug/nostr-rs-relay.git
synced 2024-11-22 00:59:07 -05:00
feat(NIP-42): limit access to kind 4 DMs
This commit is contained in:
parent
c13961a5c4
commit
8e4e2d824b
|
@ -148,6 +148,8 @@ reject_future_seconds = 1800
|
||||||
#]
|
#]
|
||||||
# Enable NIP-42 authentication
|
# Enable NIP-42 authentication
|
||||||
#nip42_auth = false
|
#nip42_auth = false
|
||||||
|
# Send DMs events (kind 4) only to their authenticated recipients
|
||||||
|
#nip42_dms = false
|
||||||
|
|
||||||
[verified_users]
|
[verified_users]
|
||||||
# NIP-05 verification of users. Can be "enabled" to require NIP-05
|
# NIP-05 verification of users. Can be "enabled" to require NIP-05
|
||||||
|
|
|
@ -80,6 +80,7 @@ pub struct Limits {
|
||||||
pub struct Authorization {
|
pub struct Authorization {
|
||||||
pub pubkey_whitelist: Option<Vec<String>>, // If present, only allow these pubkeys to publish events
|
pub pubkey_whitelist: Option<Vec<String>>, // If present, only allow these pubkeys to publish events
|
||||||
pub nip42_auth: bool, // if true enables NIP-42 authentication
|
pub nip42_auth: bool, // if true enables NIP-42 authentication
|
||||||
|
pub nip42_dms: bool, // if true send DMs only to their authenticated recipients
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
@ -285,6 +286,7 @@ impl Default for Settings {
|
||||||
authorization: Authorization {
|
authorization: Authorization {
|
||||||
pubkey_whitelist: None, // Allow any address to publish
|
pubkey_whitelist: None, // Allow any address to publish
|
||||||
nip42_auth: false, // Disable NIP-42 authentication
|
nip42_auth: false, // Disable NIP-42 authentication
|
||||||
|
nip42_dms: false, // Send DMs to everybody
|
||||||
},
|
},
|
||||||
pay_to_relay: PayToRelay {
|
pay_to_relay: PayToRelay {
|
||||||
enabled: false,
|
enabled: false,
|
||||||
|
|
|
@ -1029,6 +1029,31 @@ fn make_notice_message(notice: &Notice) -> Message {
|
||||||
Message::text(json.to_string())
|
Message::text(json.to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn allowed_to_send(event_str: &String, conn: &conn::ClientConn, settings: &Settings) -> bool {
|
||||||
|
// TODO: pass in kind so that we can avoid deserialization for most events
|
||||||
|
if settings.authorization.nip42_dms {
|
||||||
|
match serde_json::from_str::<Event>(event_str) {
|
||||||
|
Ok(event) => {
|
||||||
|
if event.kind == 4 {
|
||||||
|
match (conn.auth_pubkey(), event.tag_values_by_name("p").first()) {
|
||||||
|
(Some(auth_pubkey), Some(recipient_pubkey)) => {
|
||||||
|
recipient_pubkey == auth_pubkey || &event.pubkey == auth_pubkey
|
||||||
|
},
|
||||||
|
(_, _) => {
|
||||||
|
false
|
||||||
|
},
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Err(_) => false
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct ClientInfo {
|
struct ClientInfo {
|
||||||
remote_ip: String,
|
remote_ip: String,
|
||||||
user_agent: Option<String>,
|
user_agent: Option<String>,
|
||||||
|
@ -1151,12 +1176,14 @@ async fn nostr_server(
|
||||||
let send_str = format!("[\"EOSE\",\"{subesc}\"]");
|
let send_str = format!("[\"EOSE\",\"{subesc}\"]");
|
||||||
ws_stream.send(Message::Text(send_str)).await.ok();
|
ws_stream.send(Message::Text(send_str)).await.ok();
|
||||||
} else {
|
} else {
|
||||||
client_received_event_count += 1;
|
if allowed_to_send(&query_result.event, &conn, &settings) {
|
||||||
metrics.sent_events.with_label_values(&["db"]).inc();
|
metrics.sent_events.with_label_values(&["db"]).inc();
|
||||||
|
client_received_event_count += 1;
|
||||||
// send a result
|
// send a result
|
||||||
let send_str = format!("[\"EVENT\",\"{}\",{}]", subesc, &query_result.event);
|
let send_str = format!("[\"EVENT\",\"{}\",{}]", subesc, &query_result.event);
|
||||||
ws_stream.send(Message::Text(send_str)).await.ok();
|
ws_stream.send(Message::Text(send_str)).await.ok();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
// TODO: consider logging the LaggedRecv error
|
// TODO: consider logging the LaggedRecv error
|
||||||
Ok(global_event) = bcast_rx.recv() => {
|
Ok(global_event) = bcast_rx.recv() => {
|
||||||
|
@ -1169,13 +1196,15 @@ async fn nostr_server(
|
||||||
// TODO: serialize at broadcast time, instead of
|
// TODO: serialize at broadcast time, instead of
|
||||||
// once for each consumer.
|
// once for each consumer.
|
||||||
if let Ok(event_str) = serde_json::to_string(&global_event) {
|
if let Ok(event_str) = serde_json::to_string(&global_event) {
|
||||||
|
if allowed_to_send(&event_str, &conn, &settings) {
|
||||||
|
// create an event response and send it
|
||||||
trace!("sub match for client: {}, sub: {:?}, event: {:?}",
|
trace!("sub match for client: {}, sub: {:?}, event: {:?}",
|
||||||
cid, s,
|
cid, s,
|
||||||
global_event.get_event_id_prefix());
|
global_event.get_event_id_prefix());
|
||||||
// create an event response and send it
|
|
||||||
let subesc = s.replace('"', "");
|
let subesc = s.replace('"', "");
|
||||||
metrics.sent_events.with_label_values(&["realtime"]).inc();
|
metrics.sent_events.with_label_values(&["realtime"]).inc();
|
||||||
ws_stream.send(Message::Text(format!("[\"EVENT\",\"{subesc}\",{event_str}]"))).await.ok();
|
ws_stream.send(Message::Text(format!("[\"EVENT\",\"{subesc}\",{event_str}]"))).await.ok();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
warn!("could not serialize event: {:?}", global_event.get_event_id_prefix());
|
warn!("could not serialize event: {:?}", global_event.get_event_id_prefix());
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user