From: Felix Ableitner <me@nutomic.com>
Date: Mon, 25 Oct 2021 17:22:34 +0000 (+0200)
Subject: Activity.to should always be a vec (and unspecified size for public activities)
X-Git-Url: http://these/git/readmes/%7B%60%24%7BwebArchiveUrl%7D/save/static/README.es.md?a=commitdiff_plain;h=03b8ae72152c781db5f8834891feca1096a18a25;p=lemmy.git

Activity.to should always be a vec (and unspecified size for public activities)
---

diff --git a/crates/apub/src/activities/comment/create_or_update.rs b/crates/apub/src/activities/comment/create_or_update.rs
index 0dcf3f7d..9ccf49f0 100644
--- a/crates/apub/src/activities/comment/create_or_update.rs
+++ b/crates/apub/src/activities/comment/create_or_update.rs
@@ -6,6 +6,7 @@ use crate::{
     extract_community,
     generate_activity_id,
     verify_activity,
+    verify_is_public,
     verify_person_in_community,
     CreateOrUpdateType,
   },
@@ -17,12 +18,17 @@ use crate::{
     person::ApubPerson,
   },
 };
-use activitystreams::{base::AnyBase, link::Mention, primitives::OneOrMany, unparsed::Unparsed};
+use activitystreams::{
+  base::AnyBase,
+  link::Mention,
+  primitives::OneOrMany,
+  public,
+  unparsed::Unparsed,
+};
 use lemmy_api_common::{blocking, check_post_deleted_or_removed};
 use lemmy_apub_lib::{
   data::Data,
   traits::{ActivityFields, ActivityHandler, ActorType, ApubObject},
-  values::PublicUrl,
   verify::verify_domains_match,
 };
 use lemmy_db_schema::{
@@ -38,7 +44,7 @@ use url::Url;
 #[serde(rename_all = "camelCase")]
 pub struct CreateOrUpdateComment {
   actor: ObjectId<ApubPerson>,
-  to: [PublicUrl; 1],
+  to: Vec<Url>,
   object: Note,
   cc: Vec<Url>,
   tag: Vec<Mention>,
@@ -76,7 +82,7 @@ impl CreateOrUpdateComment {
 
     let create_or_update = CreateOrUpdateComment {
       actor: ObjectId::new(actor.actor_id()),
-      to: [PublicUrl::Public],
+      to: vec![public()],
       object: comment.to_apub(context).await?,
       cc: maa.ccs,
       tag: maa.tags,
@@ -100,6 +106,7 @@ impl ActivityHandler for CreateOrUpdateComment {
     context: &Data<LemmyContext>,
     request_counter: &mut i32,
   ) -> Result<(), LemmyError> {
+    verify_is_public(&self.to)?;
     let community = extract_community(&self.cc, context, request_counter).await?;
     let community_id = ObjectId::new(community.actor_id());
     let post = self.object.get_parents(context, request_counter).await?.0;
diff --git a/crates/apub/src/activities/community/add_mod.rs b/crates/apub/src/activities/community/add_mod.rs
index e1cf03e0..6df6f812 100644
--- a/crates/apub/src/activities/community/add_mod.rs
+++ b/crates/apub/src/activities/community/add_mod.rs
@@ -4,6 +4,7 @@ use crate::{
     generate_activity_id,
     verify_activity,
     verify_add_remove_moderator_target,
+    verify_is_public,
     verify_mod_action,
     verify_person_in_community,
   },
@@ -16,13 +17,13 @@ use activitystreams::{
   activity::kind::AddType,
   base::AnyBase,
   primitives::OneOrMany,
+  public,
   unparsed::Unparsed,
 };
 use lemmy_api_common::blocking;
 use lemmy_apub_lib::{
   data::Data,
   traits::{ActivityFields, ActivityHandler, ActorType},
-  values::PublicUrl,
 };
 use lemmy_db_schema::{
   source::community::{CommunityModerator, CommunityModeratorForm},
@@ -37,7 +38,7 @@ use url::Url;
 #[serde(rename_all = "camelCase")]
 pub struct AddMod {
   actor: ObjectId<ApubPerson>,
-  to: [PublicUrl; 1],
+  to: Vec<Url>,
   object: ObjectId<ApubPerson>,
   target: Url,
   cc: [ObjectId<ApubCommunity>; 1],
@@ -63,7 +64,7 @@ impl AddMod {
     )?;
     let add = AddMod {
       actor: ObjectId::new(actor.actor_id()),
-      to: [PublicUrl::Public],
+      to: vec![public()],
       object: ObjectId::new(added_mod.actor_id()),
       target: generate_moderators_url(&community.actor_id)?.into(),
       cc: [ObjectId::new(community.actor_id())],
@@ -88,6 +89,7 @@ impl ActivityHandler for AddMod {
     context: &Data<LemmyContext>,
     request_counter: &mut i32,
   ) -> Result<(), LemmyError> {
+    verify_is_public(&self.to)?;
     verify_activity(self, &context.settings())?;
     verify_person_in_community(&self.actor, &self.cc[0], context, request_counter).await?;
     verify_mod_action(&self.actor, &self.cc[0], context, request_counter).await?;
diff --git a/crates/apub/src/activities/community/announce.rs b/crates/apub/src/activities/community/announce.rs
index f3dc72c5..deca2b73 100644
--- a/crates/apub/src/activities/community/announce.rs
+++ b/crates/apub/src/activities/community/announce.rs
@@ -14,6 +14,7 @@ use crate::{
     post::create_or_update::CreateOrUpdatePost,
     verify_activity,
     verify_community,
+    verify_is_public,
     voting::{undo_vote::UndoVote, vote::Vote},
   },
   context::lemmy_context,
@@ -28,12 +29,12 @@ use activitystreams::{
   activity::kind::AnnounceType,
   base::AnyBase,
   primitives::OneOrMany,
+  public,
   unparsed::Unparsed,
 };
 use lemmy_apub_lib::{
   data::Data,
   traits::{ActivityFields, ActivityHandler, ActorType},
-  values::PublicUrl,
 };
 use lemmy_utils::LemmyError;
 use lemmy_websocket::LemmyContext;
@@ -61,7 +62,7 @@ pub enum AnnouncableActivities {
 #[serde(rename_all = "camelCase")]
 pub struct AnnounceActivity {
   actor: ObjectId<ApubCommunity>,
-  to: [PublicUrl; 1],
+  to: Vec<Url>,
   object: AnnouncableActivities,
   cc: Vec<Url>,
   #[serde(rename = "type")]
@@ -82,7 +83,7 @@ impl AnnounceActivity {
   ) -> Result<(), LemmyError> {
     let announce = AnnounceActivity {
       actor: ObjectId::new(community.actor_id()),
-      to: [PublicUrl::Public],
+      to: vec![public()],
       object,
       cc: vec![community.followers_url()],
       kind: AnnounceType::Announce,
@@ -106,6 +107,7 @@ impl ActivityHandler for AnnounceActivity {
     context: &Data<LemmyContext>,
     request_counter: &mut i32,
   ) -> Result<(), LemmyError> {
+    verify_is_public(&self.to)?;
     verify_activity(self, &context.settings())?;
     verify_community(&self.actor, context, request_counter).await?;
     self.object.verify(context, request_counter).await?;
diff --git a/crates/apub/src/activities/community/block_user.rs b/crates/apub/src/activities/community/block_user.rs
index a1c76c23..64a030c8 100644
--- a/crates/apub/src/activities/community/block_user.rs
+++ b/crates/apub/src/activities/community/block_user.rs
@@ -3,6 +3,7 @@ use crate::{
     community::{announce::AnnouncableActivities, send_to_community},
     generate_activity_id,
     verify_activity,
+    verify_is_public,
     verify_mod_action,
     verify_person_in_community,
   },
@@ -14,13 +15,13 @@ use activitystreams::{
   activity::kind::BlockType,
   base::AnyBase,
   primitives::OneOrMany,
+  public,
   unparsed::Unparsed,
 };
 use lemmy_api_common::blocking;
 use lemmy_apub_lib::{
   data::Data,
   traits::{ActivityFields, ActivityHandler, ActorType},
-  values::PublicUrl,
 };
 use lemmy_db_schema::{
   source::community::{
@@ -40,7 +41,7 @@ use url::Url;
 #[serde(rename_all = "camelCase")]
 pub struct BlockUserFromCommunity {
   actor: ObjectId<ApubPerson>,
-  to: [PublicUrl; 1],
+  to: Vec<Url>,
   pub(in crate::activities::community) object: ObjectId<ApubPerson>,
   cc: [ObjectId<ApubCommunity>; 1],
   #[serde(rename = "type")]
@@ -61,7 +62,7 @@ impl BlockUserFromCommunity {
   ) -> Result<BlockUserFromCommunity, LemmyError> {
     Ok(BlockUserFromCommunity {
       actor: ObjectId::new(actor.actor_id()),
-      to: [PublicUrl::Public],
+      to: vec![public()],
       object: ObjectId::new(target.actor_id()),
       cc: [ObjectId::new(community.actor_id())],
       kind: BlockType::Block,
@@ -97,6 +98,7 @@ impl ActivityHandler for BlockUserFromCommunity {
     context: &Data<LemmyContext>,
     request_counter: &mut i32,
   ) -> Result<(), LemmyError> {
+    verify_is_public(&self.to)?;
     verify_activity(self, &context.settings())?;
     verify_person_in_community(&self.actor, &self.cc[0], context, request_counter).await?;
     verify_mod_action(&self.actor, &self.cc[0], context, request_counter).await?;
diff --git a/crates/apub/src/activities/community/remove_mod.rs b/crates/apub/src/activities/community/remove_mod.rs
index 9f4c9ae6..d1a5675a 100644
--- a/crates/apub/src/activities/community/remove_mod.rs
+++ b/crates/apub/src/activities/community/remove_mod.rs
@@ -4,6 +4,7 @@ use crate::{
     generate_activity_id,
     verify_activity,
     verify_add_remove_moderator_target,
+    verify_is_public,
     verify_mod_action,
     verify_person_in_community,
   },
@@ -16,13 +17,13 @@ use activitystreams::{
   activity::kind::RemoveType,
   base::AnyBase,
   primitives::OneOrMany,
+  public,
   unparsed::Unparsed,
 };
 use lemmy_api_common::blocking;
 use lemmy_apub_lib::{
   data::Data,
   traits::{ActivityFields, ActivityHandler, ActorType},
-  values::PublicUrl,
 };
 use lemmy_db_schema::{
   source::community::{CommunityModerator, CommunityModeratorForm},
@@ -37,7 +38,7 @@ use url::Url;
 #[serde(rename_all = "camelCase")]
 pub struct RemoveMod {
   actor: ObjectId<ApubPerson>,
-  to: [PublicUrl; 1],
+  to: Vec<Url>,
   pub(in crate::activities) object: ObjectId<ApubPerson>,
   cc: [ObjectId<ApubCommunity>; 1],
   #[serde(rename = "type")]
@@ -64,7 +65,7 @@ impl RemoveMod {
     )?;
     let remove = RemoveMod {
       actor: ObjectId::new(actor.actor_id()),
-      to: [PublicUrl::Public],
+      to: vec![public()],
       object: ObjectId::new(removed_mod.actor_id()),
       target: generate_moderators_url(&community.actor_id)?.into(),
       id: id.clone(),
@@ -88,6 +89,7 @@ impl ActivityHandler for RemoveMod {
     context: &Data<LemmyContext>,
     request_counter: &mut i32,
   ) -> Result<(), LemmyError> {
+    verify_is_public(&self.to)?;
     verify_activity(self, &context.settings())?;
     verify_person_in_community(&self.actor, &self.cc[0], context, request_counter).await?;
     verify_mod_action(&self.actor, &self.cc[0], context, request_counter).await?;
diff --git a/crates/apub/src/activities/community/undo_block_user.rs b/crates/apub/src/activities/community/undo_block_user.rs
index 1614de67..ee36d1ae 100644
--- a/crates/apub/src/activities/community/undo_block_user.rs
+++ b/crates/apub/src/activities/community/undo_block_user.rs
@@ -7,6 +7,7 @@ use crate::{
     },
     generate_activity_id,
     verify_activity,
+    verify_is_public,
     verify_mod_action,
     verify_person_in_community,
   },
@@ -18,13 +19,13 @@ use activitystreams::{
   activity::kind::UndoType,
   base::AnyBase,
   primitives::OneOrMany,
+  public,
   unparsed::Unparsed,
 };
 use lemmy_api_common::blocking;
 use lemmy_apub_lib::{
   data::Data,
   traits::{ActivityFields, ActivityHandler, ActorType},
-  values::PublicUrl,
 };
 use lemmy_db_schema::{
   source::community::{CommunityPersonBan, CommunityPersonBanForm},
@@ -39,7 +40,7 @@ use url::Url;
 #[serde(rename_all = "camelCase")]
 pub struct UndoBlockUserFromCommunity {
   actor: ObjectId<ApubPerson>,
-  to: [PublicUrl; 1],
+  to: Vec<Url>,
   object: BlockUserFromCommunity,
   cc: [ObjectId<ApubCommunity>; 1],
   #[serde(rename = "type")]
@@ -66,7 +67,7 @@ impl UndoBlockUserFromCommunity {
     )?;
     let undo = UndoBlockUserFromCommunity {
       actor: ObjectId::new(actor.actor_id()),
-      to: [PublicUrl::Public],
+      to: vec![public()],
       object: block,
       cc: [ObjectId::new(community.actor_id())],
       kind: UndoType::Undo,
@@ -89,6 +90,7 @@ impl ActivityHandler for UndoBlockUserFromCommunity {
     context: &Data<LemmyContext>,
     request_counter: &mut i32,
   ) -> Result<(), LemmyError> {
+    verify_is_public(&self.to)?;
     verify_activity(self, &context.settings())?;
     verify_person_in_community(&self.actor, &self.cc[0], context, request_counter).await?;
     verify_mod_action(&self.actor, &self.cc[0], context, request_counter).await?;
diff --git a/crates/apub/src/activities/community/update.rs b/crates/apub/src/activities/community/update.rs
index f6d693dd..6c78dbfb 100644
--- a/crates/apub/src/activities/community/update.rs
+++ b/crates/apub/src/activities/community/update.rs
@@ -3,6 +3,7 @@ use crate::{
     community::{announce::AnnouncableActivities, send_to_community},
     generate_activity_id,
     verify_activity,
+    verify_is_public,
     verify_mod_action,
     verify_person_in_community,
   },
@@ -17,13 +18,13 @@ use activitystreams::{
   activity::kind::UpdateType,
   base::AnyBase,
   primitives::OneOrMany,
+  public,
   unparsed::Unparsed,
 };
 use lemmy_api_common::blocking;
 use lemmy_apub_lib::{
   data::Data,
   traits::{ActivityFields, ActivityHandler, ActorType, ApubObject},
-  values::PublicUrl,
 };
 use lemmy_db_schema::{
   source::community::{Community, CommunityForm},
@@ -40,7 +41,7 @@ use url::Url;
 #[serde(rename_all = "camelCase")]
 pub struct UpdateCommunity {
   actor: ObjectId<ApubPerson>,
-  to: [PublicUrl; 1],
+  to: Vec<Url>,
   // TODO: would be nice to use a separate struct here, which only contains the fields updated here
   object: Group,
   cc: [ObjectId<ApubCommunity>; 1],
@@ -65,7 +66,7 @@ impl UpdateCommunity {
     )?;
     let update = UpdateCommunity {
       actor: ObjectId::new(actor.actor_id()),
-      to: [PublicUrl::Public],
+      to: vec![public()],
       object: community.to_apub(context).await?,
       cc: [ObjectId::new(community.actor_id())],
       kind: UpdateType::Update,
@@ -87,6 +88,7 @@ impl ActivityHandler for UpdateCommunity {
     context: &Data<LemmyContext>,
     request_counter: &mut i32,
   ) -> Result<(), LemmyError> {
+    verify_is_public(&self.to)?;
     verify_activity(self, &context.settings())?;
     verify_person_in_community(&self.actor, &self.cc[0], context, request_counter).await?;
     verify_mod_action(&self.actor, &self.cc[0], context, request_counter).await?;
diff --git a/crates/apub/src/activities/deletion/delete.rs b/crates/apub/src/activities/deletion/delete.rs
index 02df7dc3..7593c5bf 100644
--- a/crates/apub/src/activities/deletion/delete.rs
+++ b/crates/apub/src/activities/deletion/delete.rs
@@ -9,6 +9,7 @@ use crate::{
     },
     generate_activity_id,
     verify_activity,
+    verify_is_public,
   },
   context::lemmy_context,
   fetcher::object_id::ObjectId,
@@ -18,6 +19,7 @@ use activitystreams::{
   activity::kind::DeleteType,
   base::AnyBase,
   primitives::OneOrMany,
+  public,
   unparsed::Unparsed,
 };
 use anyhow::anyhow;
@@ -25,7 +27,6 @@ use lemmy_api_common::blocking;
 use lemmy_apub_lib::{
   data::Data,
   traits::{ActivityFields, ActivityHandler, ActorType},
-  values::PublicUrl,
 };
 use lemmy_db_schema::{
   source::{
@@ -66,7 +67,7 @@ use url::Url;
 #[serde(rename_all = "camelCase")]
 pub struct Delete {
   actor: ObjectId<ApubPerson>,
-  to: [PublicUrl; 1],
+  to: Vec<Url>,
   pub(in crate::activities::deletion) object: Url,
   pub(in crate::activities::deletion) cc: [ObjectId<ApubCommunity>; 1],
   #[serde(rename = "type")]
@@ -89,6 +90,7 @@ impl ActivityHandler for Delete {
     context: &Data<LemmyContext>,
     request_counter: &mut i32,
   ) -> Result<(), LemmyError> {
+    verify_is_public(&self.to)?;
     verify_activity(self, &context.settings())?;
     verify_delete_activity(
       &self.object,
@@ -144,7 +146,7 @@ impl Delete {
   ) -> Result<Delete, LemmyError> {
     Ok(Delete {
       actor: ObjectId::new(actor.actor_id()),
-      to: [PublicUrl::Public],
+      to: vec![public()],
       object: object_id,
       cc: [ObjectId::new(community.actor_id())],
       kind: DeleteType::Delete,
diff --git a/crates/apub/src/activities/deletion/undo_delete.rs b/crates/apub/src/activities/deletion/undo_delete.rs
index 327bf86c..87c8eae7 100644
--- a/crates/apub/src/activities/deletion/undo_delete.rs
+++ b/crates/apub/src/activities/deletion/undo_delete.rs
@@ -10,6 +10,7 @@ use crate::{
     },
     generate_activity_id,
     verify_activity,
+    verify_is_public,
   },
   context::lemmy_context,
   fetcher::object_id::ObjectId,
@@ -19,6 +20,7 @@ use activitystreams::{
   activity::kind::UndoType,
   base::AnyBase,
   primitives::OneOrMany,
+  public,
   unparsed::Unparsed,
 };
 use anyhow::anyhow;
@@ -26,7 +28,6 @@ use lemmy_api_common::blocking;
 use lemmy_apub_lib::{
   data::Data,
   traits::{ActivityFields, ActivityHandler, ActorType},
-  values::PublicUrl,
 };
 use lemmy_db_schema::source::{comment::Comment, community::Community, post::Post};
 use lemmy_utils::LemmyError;
@@ -42,7 +43,7 @@ use url::Url;
 #[serde(rename_all = "camelCase")]
 pub struct UndoDelete {
   actor: ObjectId<ApubPerson>,
-  to: [PublicUrl; 1],
+  to: Vec<Url>,
   object: Delete,
   cc: [ObjectId<ApubCommunity>; 1],
   #[serde(rename = "type")]
@@ -62,6 +63,7 @@ impl ActivityHandler for UndoDelete {
     context: &Data<LemmyContext>,
     request_counter: &mut i32,
   ) -> Result<(), LemmyError> {
+    verify_is_public(&self.to)?;
     verify_activity(self, &context.settings())?;
     self.object.verify(context, request_counter).await?;
     verify_delete_activity(
@@ -117,7 +119,7 @@ impl UndoDelete {
     )?;
     let undo = UndoDelete {
       actor: ObjectId::new(actor.actor_id()),
-      to: [PublicUrl::Public],
+      to: vec![public()],
       object,
       cc: [ObjectId::new(community.actor_id())],
       kind: UndoType::Undo,
diff --git a/crates/apub/src/activities/following/accept.rs b/crates/apub/src/activities/following/accept.rs
index 6fa65e7b..78d12b52 100644
--- a/crates/apub/src/activities/following/accept.rs
+++ b/crates/apub/src/activities/following/accept.rs
@@ -32,7 +32,7 @@ use url::Url;
 #[serde(rename_all = "camelCase")]
 pub struct AcceptFollowCommunity {
   actor: ObjectId<ApubCommunity>,
-  to: ObjectId<ApubPerson>,
+  to: [ObjectId<ApubPerson>; 1],
   object: FollowCommunity,
   #[serde(rename = "type")]
   kind: AcceptType,
@@ -57,7 +57,7 @@ impl AcceptFollowCommunity {
       .await?;
     let accept = AcceptFollowCommunity {
       actor: ObjectId::new(community.actor_id()),
-      to: ObjectId::new(person.actor_id()),
+      to: [ObjectId::new(person.actor_id())],
       object: follow,
       kind: AcceptType::Accept,
       id: generate_activity_id(
@@ -82,8 +82,8 @@ impl ActivityHandler for AcceptFollowCommunity {
     request_counter: &mut i32,
   ) -> Result<(), LemmyError> {
     verify_activity(self, &context.settings())?;
-    verify_urls_match(self.to.inner(), self.object.actor())?;
-    verify_urls_match(self.actor(), self.object.to.inner())?;
+    verify_urls_match(self.to[0].inner(), self.object.actor())?;
+    verify_urls_match(self.actor(), self.object.to[0].inner())?;
     verify_community(&self.actor, context, request_counter).await?;
     self.object.verify(context, request_counter).await?;
     Ok(())
@@ -95,7 +95,7 @@ impl ActivityHandler for AcceptFollowCommunity {
     request_counter: &mut i32,
   ) -> Result<(), LemmyError> {
     let actor = self.actor.dereference(context, request_counter).await?;
-    let to = self.to.dereference(context, request_counter).await?;
+    let to = self.to[0].dereference(context, request_counter).await?;
     // This will throw an error if no follow was requested
     blocking(context.pool(), move |conn| {
       CommunityFollower::follow_accepted(conn, actor.id, to.id)
diff --git a/crates/apub/src/activities/following/follow.rs b/crates/apub/src/activities/following/follow.rs
index 14424381..82d2d540 100644
--- a/crates/apub/src/activities/following/follow.rs
+++ b/crates/apub/src/activities/following/follow.rs
@@ -35,8 +35,7 @@ use url::Url;
 #[serde(rename_all = "camelCase")]
 pub struct FollowCommunity {
   pub(in crate::activities::following) actor: ObjectId<ApubPerson>,
-  // TODO: is there any reason to put the same community id twice, in to and object?
-  pub(in crate::activities::following) to: ObjectId<ApubCommunity>,
+  pub(in crate::activities::following) to: [ObjectId<ApubCommunity>; 1],
   pub(in crate::activities::following) object: ObjectId<ApubCommunity>,
   #[serde(rename = "type")]
   kind: FollowType,
@@ -55,7 +54,7 @@ impl FollowCommunity {
   ) -> Result<FollowCommunity, LemmyError> {
     Ok(FollowCommunity {
       actor: ObjectId::new(actor.actor_id()),
-      to: ObjectId::new(community.actor_id()),
+      to: [ObjectId::new(community.actor_id())],
       object: ObjectId::new(community.actor_id()),
       kind: FollowType::Follow,
       id: generate_activity_id(
@@ -96,7 +95,7 @@ impl ActivityHandler for FollowCommunity {
     request_counter: &mut i32,
   ) -> Result<(), LemmyError> {
     verify_activity(self, &context.settings())?;
-    verify_urls_match(self.to.inner(), self.object.inner())?;
+    verify_urls_match(self.to[0].inner(), self.object.inner())?;
     verify_person(&self.actor, context, request_counter).await?;
     Ok(())
   }
@@ -107,7 +106,7 @@ impl ActivityHandler for FollowCommunity {
     request_counter: &mut i32,
   ) -> Result<(), LemmyError> {
     let actor = self.actor.dereference(context, request_counter).await?;
-    let community = self.object.dereference(context, request_counter).await?;
+    let community = self.to[0].dereference(context, request_counter).await?;
     let community_follower_form = CommunityFollowerForm {
       community_id: community.id,
       person_id: actor.id,
diff --git a/crates/apub/src/activities/following/undo.rs b/crates/apub/src/activities/following/undo.rs
index 5c548ae4..7abb6117 100644
--- a/crates/apub/src/activities/following/undo.rs
+++ b/crates/apub/src/activities/following/undo.rs
@@ -35,7 +35,7 @@ use url::Url;
 #[serde(rename_all = "camelCase")]
 pub struct UndoFollowCommunity {
   actor: ObjectId<ApubPerson>,
-  to: ObjectId<ApubCommunity>,
+  to: [ObjectId<ApubCommunity>; 1],
   object: FollowCommunity,
   #[serde(rename = "type")]
   kind: UndoType,
@@ -55,7 +55,7 @@ impl UndoFollowCommunity {
     let object = FollowCommunity::new(actor, community, context)?;
     let undo = UndoFollowCommunity {
       actor: ObjectId::new(actor.actor_id()),
-      to: ObjectId::new(community.actor_id()),
+      to: [ObjectId::new(community.actor_id())],
       object,
       kind: UndoType::Undo,
       id: generate_activity_id(
@@ -79,7 +79,7 @@ impl ActivityHandler for UndoFollowCommunity {
     request_counter: &mut i32,
   ) -> Result<(), LemmyError> {
     verify_activity(self, &context.settings())?;
-    verify_urls_match(self.to.inner(), self.object.object.inner())?;
+    verify_urls_match(self.to[0].inner(), self.object.object.inner())?;
     verify_urls_match(self.actor(), self.object.actor())?;
     verify_person(&self.actor, context, request_counter).await?;
     self.object.verify(context, request_counter).await?;
@@ -92,7 +92,7 @@ impl ActivityHandler for UndoFollowCommunity {
     request_counter: &mut i32,
   ) -> Result<(), LemmyError> {
     let actor = self.actor.dereference(context, request_counter).await?;
-    let community = self.to.dereference(context, request_counter).await?;
+    let community = self.to[0].dereference(context, request_counter).await?;
 
     let community_follower_form = CommunityFollowerForm {
       community_id: community.id,
diff --git a/crates/apub/src/activities/post/create_or_update.rs b/crates/apub/src/activities/post/create_or_update.rs
index 4a048a96..b3c0b694 100644
--- a/crates/apub/src/activities/post/create_or_update.rs
+++ b/crates/apub/src/activities/post/create_or_update.rs
@@ -4,6 +4,7 @@ use crate::{
     community::{announce::AnnouncableActivities, send_to_community},
     generate_activity_id,
     verify_activity,
+    verify_is_public,
     verify_mod_action,
     verify_person_in_community,
     CreateOrUpdateType,
@@ -16,13 +17,12 @@ use crate::{
     post::{ApubPost, Page},
   },
 };
-use activitystreams::{base::AnyBase, primitives::OneOrMany, unparsed::Unparsed};
+use activitystreams::{base::AnyBase, primitives::OneOrMany, public, unparsed::Unparsed};
 use anyhow::anyhow;
 use lemmy_api_common::blocking;
 use lemmy_apub_lib::{
   data::Data,
   traits::{ActivityFields, ActivityHandler, ActorType, ApubObject},
-  values::PublicUrl,
   verify::{verify_domains_match, verify_urls_match},
 };
 use lemmy_db_schema::{source::community::Community, traits::Crud};
@@ -35,7 +35,7 @@ use url::Url;
 #[serde(rename_all = "camelCase")]
 pub struct CreateOrUpdatePost {
   actor: ObjectId<ApubPerson>,
-  to: [PublicUrl; 1],
+  to: Vec<Url>,
   object: Page,
   cc: [ObjectId<ApubCommunity>; 1],
   #[serde(rename = "type")]
@@ -61,7 +61,7 @@ impl CreateOrUpdatePost {
     )?;
     Ok(CreateOrUpdatePost {
       actor: ObjectId::new(actor.actor_id()),
-      to: [PublicUrl::Public],
+      to: vec![public()],
       object: post.to_apub(context).await?,
       cc: [ObjectId::new(community.actor_id())],
       kind,
@@ -97,6 +97,7 @@ impl ActivityHandler for CreateOrUpdatePost {
     context: &Data<LemmyContext>,
     request_counter: &mut i32,
   ) -> Result<(), LemmyError> {
+    verify_is_public(&self.to)?;
     verify_activity(self, &context.settings())?;
     let community = self.cc[0].dereference(context, request_counter).await?;
     verify_person_in_community(&self.actor, &self.cc[0], context, request_counter).await?;
diff --git a/crates/apub/src/activities/private_message/create_or_update.rs b/crates/apub/src/activities/private_message/create_or_update.rs
index 9ef22f0e..d6552b37 100644
--- a/crates/apub/src/activities/private_message/create_or_update.rs
+++ b/crates/apub/src/activities/private_message/create_or_update.rs
@@ -28,7 +28,7 @@ pub struct CreateOrUpdatePrivateMessage {
   pub context: OneOrMany<AnyBase>,
   id: Url,
   actor: ObjectId<ApubPerson>,
-  to: ObjectId<ApubPerson>,
+  to: [ObjectId<ApubPerson>; 1],
   object: Note,
   #[serde(rename = "type")]
   kind: CreateOrUpdateType,
@@ -57,7 +57,7 @@ impl CreateOrUpdatePrivateMessage {
       context: lemmy_context(),
       id: id.clone(),
       actor: ObjectId::new(actor.actor_id()),
-      to: ObjectId::new(recipient.actor_id()),
+      to: [ObjectId::new(recipient.actor_id())],
       object: private_message.to_apub(context).await?,
       kind,
       unparsed: Default::default(),
diff --git a/crates/apub/src/activities/private_message/delete.rs b/crates/apub/src/activities/private_message/delete.rs
index bb374eb4..bcd9542c 100644
--- a/crates/apub/src/activities/private_message/delete.rs
+++ b/crates/apub/src/activities/private_message/delete.rs
@@ -30,7 +30,7 @@ use url::Url;
 #[serde(rename_all = "camelCase")]
 pub struct DeletePrivateMessage {
   actor: ObjectId<ApubPerson>,
-  to: ObjectId<ApubPerson>,
+  to: [ObjectId<ApubPerson>; 1],
   pub(in crate::activities::private_message) object: ObjectId<ApubPrivateMessage>,
   #[serde(rename = "type")]
   kind: DeleteType,
@@ -49,7 +49,7 @@ impl DeletePrivateMessage {
   ) -> Result<DeletePrivateMessage, LemmyError> {
     Ok(DeletePrivateMessage {
       actor: ObjectId::new(actor.actor_id()),
-      to: ObjectId::new(actor.actor_id()),
+      to: [ObjectId::new(actor.actor_id())],
       object: ObjectId::new(pm.ap_id.clone()),
       kind: DeleteType::Delete,
       id: generate_activity_id(
diff --git a/crates/apub/src/activities/private_message/undo_delete.rs b/crates/apub/src/activities/private_message/undo_delete.rs
index 0263b811..cdabaa9a 100644
--- a/crates/apub/src/activities/private_message/undo_delete.rs
+++ b/crates/apub/src/activities/private_message/undo_delete.rs
@@ -35,7 +35,7 @@ use url::Url;
 #[serde(rename_all = "camelCase")]
 pub struct UndoDeletePrivateMessage {
   actor: ObjectId<ApubPerson>,
-  to: ObjectId<ApubPerson>,
+  to: [ObjectId<ApubPerson>; 1],
   object: DeletePrivateMessage,
   #[serde(rename = "type")]
   kind: UndoType,
@@ -65,7 +65,7 @@ impl UndoDeletePrivateMessage {
     )?;
     let undo = UndoDeletePrivateMessage {
       actor: ObjectId::new(actor.actor_id()),
-      to: ObjectId::new(recipient.actor_id()),
+      to: [ObjectId::new(recipient.actor_id())],
       object,
       kind: UndoType::Undo,
       id: id.clone(),
diff --git a/crates/apub/src/activities/voting/undo_vote.rs b/crates/apub/src/activities/voting/undo_vote.rs
index d72b5245..1ac1d4d8 100644
--- a/crates/apub/src/activities/voting/undo_vote.rs
+++ b/crates/apub/src/activities/voting/undo_vote.rs
@@ -3,6 +3,7 @@ use crate::{
     community::{announce::AnnouncableActivities, send_to_community},
     generate_activity_id,
     verify_activity,
+    verify_is_public,
     verify_person_in_community,
     voting::{
       undo_vote_comment,
@@ -19,13 +20,13 @@ use activitystreams::{
   activity::kind::UndoType,
   base::AnyBase,
   primitives::OneOrMany,
+  public,
   unparsed::Unparsed,
 };
 use lemmy_api_common::blocking;
 use lemmy_apub_lib::{
   data::Data,
   traits::{ActivityFields, ActivityHandler, ActorType},
-  values::PublicUrl,
   verify::verify_urls_match,
 };
 use lemmy_db_schema::{newtypes::CommunityId, source::community::Community, traits::Crud};
@@ -39,7 +40,7 @@ use url::Url;
 #[serde(rename_all = "camelCase")]
 pub struct UndoVote {
   actor: ObjectId<ApubPerson>,
-  to: [PublicUrl; 1],
+  to: Vec<Url>,
   object: Vote,
   cc: [ObjectId<ApubCommunity>; 1],
   #[serde(rename = "type")]
@@ -72,7 +73,7 @@ impl UndoVote {
     )?;
     let undo_vote = UndoVote {
       actor: ObjectId::new(actor.actor_id()),
-      to: [PublicUrl::Public],
+      to: vec![public()],
       object,
       cc: [ObjectId::new(community.actor_id())],
       kind: UndoType::Undo,
@@ -93,6 +94,7 @@ impl ActivityHandler for UndoVote {
     context: &Data<LemmyContext>,
     request_counter: &mut i32,
   ) -> Result<(), LemmyError> {
+    verify_is_public(&self.to)?;
     verify_activity(self, &context.settings())?;
     verify_person_in_community(&self.actor, &self.cc[0], context, request_counter).await?;
     verify_urls_match(self.actor(), self.object.actor())?;
diff --git a/crates/apub/src/activities/voting/vote.rs b/crates/apub/src/activities/voting/vote.rs
index 5d4c9066..166ce733 100644
--- a/crates/apub/src/activities/voting/vote.rs
+++ b/crates/apub/src/activities/voting/vote.rs
@@ -3,6 +3,7 @@ use crate::{
     community::{announce::AnnouncableActivities, send_to_community},
     generate_activity_id,
     verify_activity,
+    verify_is_public,
     verify_person_in_community,
     voting::{vote_comment, vote_post},
   },
@@ -11,13 +12,12 @@ use crate::{
   objects::{community::ApubCommunity, person::ApubPerson},
   PostOrComment,
 };
-use activitystreams::{base::AnyBase, primitives::OneOrMany, unparsed::Unparsed};
+use activitystreams::{base::AnyBase, primitives::OneOrMany, public, unparsed::Unparsed};
 use anyhow::anyhow;
 use lemmy_api_common::blocking;
 use lemmy_apub_lib::{
   data::Data,
   traits::{ActivityFields, ActivityHandler, ActorType},
-  values::PublicUrl,
 };
 use lemmy_db_schema::{newtypes::CommunityId, source::community::Community, traits::Crud};
 use lemmy_utils::LemmyError;
@@ -58,7 +58,7 @@ impl From<&VoteType> for i16 {
 #[serde(rename_all = "camelCase")]
 pub struct Vote {
   actor: ObjectId<ApubPerson>,
-  to: [PublicUrl; 1],
+  to: Vec<Url>,
   pub(in crate::activities::voting) object: ObjectId<PostOrComment>,
   cc: [ObjectId<ApubCommunity>; 1],
   #[serde(rename = "type")]
@@ -80,7 +80,7 @@ impl Vote {
   ) -> Result<Vote, LemmyError> {
     Ok(Vote {
       actor: ObjectId::new(actor.actor_id()),
-      to: [PublicUrl::Public],
+      to: vec![public()],
       object: ObjectId::new(object.ap_id()),
       cc: [ObjectId::new(community.actor_id())],
       kind: kind.clone(),
@@ -118,6 +118,7 @@ impl ActivityHandler for Vote {
     context: &Data<LemmyContext>,
     request_counter: &mut i32,
   ) -> Result<(), LemmyError> {
+    verify_is_public(&self.to)?;
     verify_activity(self, &context.settings())?;
     verify_person_in_community(&self.actor, &self.cc[0], context, request_counter).await?;
     Ok(())
diff --git a/crates/apub/src/http/community.rs b/crates/apub/src/http/community.rs
index dcaf551f..a7e66d8a 100644
--- a/crates/apub/src/http/community.rs
+++ b/crates/apub/src/http/community.rs
@@ -32,7 +32,7 @@ use lemmy_db_schema::source::community::Community;
 use lemmy_db_views_actor::community_follower_view::CommunityFollowerView;
 use lemmy_utils::LemmyError;
 use lemmy_websocket::LemmyContext;
-use log::trace;
+use log::info;
 use serde::{Deserialize, Serialize};
 
 #[derive(Deserialize)]
@@ -78,7 +78,7 @@ pub async fn community_inbox(
   context: web::Data<LemmyContext>,
 ) -> Result<HttpResponse, LemmyError> {
   let unparsed = payload_to_string(payload).await?;
-  trace!("Received community inbox activity {}", unparsed);
+  info!("Received community inbox activity {}", unparsed);
   let activity = serde_json::from_str::<GroupInboxActivities>(&unparsed)?;
 
   receive_group_inbox(activity.clone(), request, &context).await?;
diff --git a/crates/apub/src/http/mod.rs b/crates/apub/src/http/mod.rs
index b82a6d89..fe44d5e3 100644
--- a/crates/apub/src/http/mod.rs
+++ b/crates/apub/src/http/mod.rs
@@ -27,7 +27,7 @@ use lemmy_apub_lib::{
 use lemmy_db_schema::{source::activity::Activity, DbPool};
 use lemmy_utils::{location_info, LemmyError};
 use lemmy_websocket::LemmyContext;
-use log::{info, trace};
+use log::info;
 use serde::{Deserialize, Serialize};
 use std::{fmt::Debug, io::Read};
 use url::Url;
@@ -54,7 +54,7 @@ pub async fn shared_inbox(
   context: web::Data<LemmyContext>,
 ) -> Result<HttpResponse, LemmyError> {
   let unparsed = payload_to_string(payload).await?;
-  trace!("Received shared inbox activity {}", unparsed);
+  info!("Received shared inbox activity {}", unparsed);
   let activity = serde_json::from_str::<SharedInboxActivities>(&unparsed)?;
   match activity {
     SharedInboxActivities::GroupInboxActivities(g) => {
diff --git a/crates/apub/src/http/person.rs b/crates/apub/src/http/person.rs
index a7e94020..88ffa120 100644
--- a/crates/apub/src/http/person.rs
+++ b/crates/apub/src/http/person.rs
@@ -28,7 +28,7 @@ use lemmy_apub_lib::traits::{ActivityFields, ActivityHandler, ApubObject};
 use lemmy_db_schema::source::person::Person;
 use lemmy_utils::LemmyError;
 use lemmy_websocket::LemmyContext;
-use log::trace;
+use log::info;
 use serde::{Deserialize, Serialize};
 use url::Url;
 
@@ -79,7 +79,7 @@ pub async fn person_inbox(
   context: web::Data<LemmyContext>,
 ) -> Result<HttpResponse, LemmyError> {
   let unparsed = payload_to_string(payload).await?;
-  trace!("Received person inbox activity {}", unparsed);
+  info!("Received person inbox activity {}", unparsed);
   let activity = serde_json::from_str::<PersonInboxActivities>(&unparsed)?;
   receive_person_inbox(activity, request, &context).await
 }
diff --git a/crates/apub_lib/src/values.rs b/crates/apub_lib/src/values.rs
index 2c9f65ff..bd014c12 100644
--- a/crates/apub_lib/src/values.rs
+++ b/crates/apub_lib/src/values.rs
@@ -33,15 +33,6 @@
 
 use serde::{Deserialize, Serialize};
 
-/// The identifier used to address activities to the public.
-///
-/// <https://www.w3.org/TR/activitypub/#public-addressing>
-#[derive(Debug, Clone, Deserialize, Serialize)]
-pub enum PublicUrl {
-  #[serde(rename = "https://www.w3.org/ns/activitystreams#Public")]
-  Public,
-}
-
 /// Media type for markdown text.
 ///
 /// <https://www.iana.org/assignments/media-types/media-types.xhtml>