diff --git a/src/activitypub/actor.rs b/src/activitypub/actor.rs index 637938a..8321e32 100644 --- a/src/activitypub/actor.rs +++ b/src/activitypub/actor.rs @@ -19,6 +19,7 @@ use super::views::{ get_outbox_url, get_followers_url, get_following_url, + get_subscribers_url, }; use super::vocabulary::{IDENTITY_PROOF, IMAGE, PERSON, PROPERTY_VALUE, SERVICE}; @@ -91,6 +92,9 @@ pub struct Actor { #[serde(skip_serializing_if = "Option::is_none")] pub following: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub subscribers: Option, + pub public_key: PublicKey, #[serde(skip_serializing_if = "Option::is_none")] @@ -237,6 +241,7 @@ pub fn get_local_actor( let outbox = get_outbox_url(instance_url, username); let followers = get_followers_url(instance_url, username); let following = get_following_url(instance_url, username); + let subscribers = get_subscribers_url(instance_url, username); let private_key = deserialize_private_key(&user.private_key)?; let public_key_pem = get_public_key_pem(&private_key)?; @@ -302,6 +307,7 @@ pub fn get_local_actor( outbox, followers: Some(followers), following: Some(following), + subscribers: Some(subscribers), public_key, capabilities: Some(capabilities), icon: avatar, @@ -338,6 +344,7 @@ pub fn get_instance_actor( outbox: actor_outbox, followers: None, following: None, + subscribers: None, public_key, capabilities: None, icon: None, diff --git a/src/activitypub/handlers/create_note.rs b/src/activitypub/handlers/create_note.rs index 518f3e5..eec5cc2 100644 --- a/src/activitypub/handlers/create_note.rs +++ b/src/activitypub/handlers/create_note.rs @@ -67,21 +67,25 @@ fn get_note_visibility( ) -> Visibility { if primary_audience.contains(&AP_PUBLIC.to_string()) || secondary_audience.contains(&AP_PUBLIC.to_string()) { - Visibility::Public - } else { - let maybe_followers = author.actor_json.as_ref() - .and_then(|actor| actor.followers.as_ref()); - if let Some(followers) = maybe_followers { - if primary_audience.contains(followers) || - secondary_audience.contains(followers) { - Visibility::Followers - } else { - Visibility::Direct - } - } else { - Visibility::Direct - } - } + return Visibility::Public; + }; + let maybe_followers = author.actor_json.as_ref() + .and_then(|actor| actor.followers.as_ref()); + if let Some(followers) = maybe_followers { + if primary_audience.contains(followers) || + secondary_audience.contains(followers) { + return Visibility::Followers; + }; + }; + let maybe_subscribers = author.actor_json.as_ref() + .and_then(|actor| actor.subscribers.as_ref()); + if let Some(subscribers) = maybe_subscribers { + if primary_audience.contains(subscribers) || + secondary_audience.contains(subscribers) { + return Visibility::Subscribers; + }; + }; + Visibility::Direct } pub async fn handle_note( @@ -338,6 +342,28 @@ mod tests { assert_eq!(visibility, Visibility::Followers); } + #[test] + fn test_get_note_visibility_subscribers() { + let author_followers = "https://example.com/users/author/followers"; + let author_subscribers = "https://example.com/users/author/subscribers"; + let author = DbActorProfile { + actor_json: Some(Actor { + followers: Some(author_followers.to_string()), + subscribers: Some(author_subscribers.to_string()), + ..Default::default() + }), + ..Default::default() + }; + let primary_audience = vec![author_subscribers.to_string()]; + let secondary_audience = vec![]; + let visibility = get_note_visibility( + &author, + primary_audience, + secondary_audience, + ); + assert_eq!(visibility, Visibility::Subscribers); + } + #[test] fn test_get_note_visibility_direct() { let author = DbActorProfile::default();