mirror of
https://github.com/mikedilger/chorus.git
synced 2026-05-03 06:51:42 +00:00
NIP-62 (PR #1256) Right to Vanish
This commit is contained in:
parent
20d1e6175a
commit
7755a413c2
110
src/nostr.rs
110
src/nostr.rs
@ -306,6 +306,21 @@ impl WebSocketService {
|
||||
}
|
||||
}
|
||||
|
||||
// Handle Request to Vanish events
|
||||
if event.kind() == Kind::from(62) {
|
||||
if let Ok(true) = verify_relay_tag(event, true) {
|
||||
let store = GLOBALS.store.get().unwrap();
|
||||
|
||||
// Erase their events (and giftwraps to them)
|
||||
store.vanish(event)?;
|
||||
|
||||
// Add their pubkey to the blocklist so their events cannot come back
|
||||
crate::mark_pubkey_approval(store, event.pubkey(), false)?;
|
||||
}
|
||||
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
// Screen the event to see if we are willing to accept it
|
||||
if !screen_incoming_event(event, event_flags, authorized_user).await? {
|
||||
if self.user.is_some() {
|
||||
@ -397,47 +412,24 @@ impl WebSocketService {
|
||||
return Err(ChorusError::AuthFailure("Wrong event kind".to_string()).into());
|
||||
}
|
||||
|
||||
// Verify the challenge and relay tags
|
||||
let mut challenge_ok = false;
|
||||
let mut relay_ok = false;
|
||||
for mut tag in event.tags()?.iter() {
|
||||
match tag.next() {
|
||||
Some(b"relay") => {
|
||||
if let Some(value) = tag.next() {
|
||||
// We check if the URL host matches
|
||||
// (when normalized, puny-encoded IDNA, etc)
|
||||
let utf8value = std::str::from_utf8(value)?;
|
||||
let url = match Url::parse(utf8value) {
|
||||
Ok(u) => u,
|
||||
Err(e) => return Err(ChorusError::AuthFailure(format!("{e}")).into()),
|
||||
};
|
||||
if let Some(h) = url.host() {
|
||||
let theirhost = h.to_owned();
|
||||
if theirhost == GLOBALS.config.read().hostname {
|
||||
relay_ok = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Some(b"challenge") => {
|
||||
if let Some(value) = tag.next() {
|
||||
if value == self.challenge.as_bytes() {
|
||||
challenge_ok = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
None => break,
|
||||
_ => continue,
|
||||
}
|
||||
}
|
||||
|
||||
if !challenge_ok {
|
||||
return Err(ChorusError::AuthFailure("challenge is wrong".to_string()).into());
|
||||
}
|
||||
// Verify the relay tag
|
||||
let relay_ok = match verify_relay_tag(event, false) {
|
||||
Ok(b) => b,
|
||||
Err(e) => return Err(ChorusError::AuthFailure(format!("{e}")).into()),
|
||||
};
|
||||
if !relay_ok {
|
||||
return Err(ChorusError::AuthFailure("relay is wrong".to_string()).into());
|
||||
}
|
||||
|
||||
// Verify the challenge tag
|
||||
let challenge_ok = match verify_challenge_tag(event, self.challenge.as_bytes()) {
|
||||
Ok(b) => b,
|
||||
Err(e) => return Err(ChorusError::AuthFailure(format!("{e}")).into()),
|
||||
};
|
||||
if !challenge_ok {
|
||||
return Err(ChorusError::AuthFailure("challenge is wrong".to_string()).into());
|
||||
}
|
||||
|
||||
// Verify the created_at timestamp is within reason
|
||||
let timediff = (Time::now().as_u64() as i64).abs_diff(event.created_at().as_u64() as i64);
|
||||
if timediff > 600 {
|
||||
@ -881,3 +873,47 @@ pub fn event_flags(event: &Event, user: &Option<Pubkey>) -> EventFlags {
|
||||
tags_current_user,
|
||||
}
|
||||
}
|
||||
|
||||
fn verify_relay_tag(event: &Event, allow_all_relays: bool) -> Result<bool, Error> {
|
||||
for mut tag in event.tags()?.iter() {
|
||||
match tag.next() {
|
||||
Some(b"relay") => {
|
||||
if let Some(value) = tag.next() {
|
||||
if allow_all_relays && value == b"ALL_RELAYS" {
|
||||
return Ok(true);
|
||||
} else {
|
||||
// We check if the URL host matches
|
||||
// (when normalized, puny-encoded IDNA, etc)
|
||||
let utf8value = std::str::from_utf8(value)?;
|
||||
let url = Url::parse(utf8value)?;
|
||||
if let Some(h) = url.host() {
|
||||
if h == GLOBALS.config.read().hostname {
|
||||
return Ok(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => continue,
|
||||
}
|
||||
}
|
||||
|
||||
Ok(false)
|
||||
}
|
||||
|
||||
fn verify_challenge_tag(event: &Event, challenge: &[u8]) -> Result<bool, Error> {
|
||||
for mut tag in event.tags()?.iter() {
|
||||
match tag.next() {
|
||||
Some(b"challenge") => {
|
||||
if let Some(value) = tag.next() {
|
||||
if value == challenge {
|
||||
return Ok(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => continue,
|
||||
}
|
||||
}
|
||||
|
||||
Ok(false)
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user