diff --git a/src/actor.rs b/src/actor.rs index 031b33b..1aab740 100644 --- a/src/actor.rs +++ b/src/actor.rs @@ -84,6 +84,28 @@ impl Actor { Some(Actor { host, kind }) } + pub fn from_object(action: &activitypub::Action) -> Option { + let action_object = action.object.as_ref()?; + + let mut action_target: Option = None; + if let Some(action_object) = action_object.as_str() { + action_target = Some(action_object.to_string()); + } + if let Some(action_object_0) = action_object.as_array() + .and_then(|action_object| { + if action_object.len() == 1 { + action_object.first() + } else { + None + } + }).and_then(|action_object_0| action_object_0.as_str()) + { + action_target = Some(action_object_0.to_string()); + } + + action_target.and_then(|action_target| Self::from_uri(&action_target)) + } + pub fn uri(&self) -> String { match &self.kind { ActorKind::TagRelay(tag) => diff --git a/src/main.rs b/src/main.rs index 8142581..edddbe8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -148,7 +148,7 @@ async fn post_language_relay( async fn post_relay( state: State, endpoint: endpoint::Endpoint<'_>, - target: actor::Actor + mut target: actor::Actor ) -> Response { if let Some((redis, in_topic)) = &state.redis { if let Ok(data) = serde_json::to_vec(&endpoint.payload) { @@ -188,6 +188,13 @@ async fn post_relay( let Ok(remote_actor) = remote_actor else { return (StatusCode::BAD_REQUEST, "Invalid actor").into_response(); }; + if let Some(action_target) = Actor::from_object(&action) { + if action_target.host == state.hostname { + // A sharedInbox receives the actual follow target in the + // `object` field. + target = action_target; + } + } let priv_key = state.priv_key.clone(); let client = state.client.clone(); tokio::spawn(async move { @@ -243,6 +250,13 @@ async fn post_relay( let Ok(remote_actor) = remote_actor else { return (StatusCode::BAD_REQUEST, "Invalid actor").into_response(); }; + if let Some(action_target) = Actor::from_object(&action) { + if action_target.host == state.hostname { + // A sharedInbox receives the actual follow target in the + // `object` field. + target = action_target; + } + } match state.database.del_follow( &remote_actor.id, &target.uri(),