diff --git a/.woodpecker.yml b/.woodpecker.yml
index c9ba830dd..51c14af7d 100644
--- a/.woodpecker.yml
+++ b/.woodpecker.yml
@@ -91,6 +91,36 @@ steps:
when:
- event: pull_request
+ cargo_clippy:
+ image: *rust_image
+ environment:
+ CARGO_HOME: .cargo_home
+ commands:
+ - rustup component add clippy
+ - cargo clippy --workspace --tests --all-targets -- -D warnings
+ when: *slow_check_paths
+
+ cargo_test:
+ image: *rust_image
+ environment:
+ LEMMY_DATABASE_URL: postgres://lemmy:password@database:5432/lemmy
+ RUST_BACKTRACE: "1"
+ CARGO_HOME: .cargo_home
+ LEMMY_TEST_FAST_FEDERATION: "1"
+ LEMMY_CONFIG_LOCATION: ../../config/config.hjson
+ commands:
+ - cargo test --workspace --no-fail-fast
+ when: *slow_check_paths
+
+ check_ts_bindings:
+ image: *rust_image
+ environment:
+ CARGO_HOME: .cargo_home
+ commands:
+ - ./scripts/ts_bindings_check.sh
+ when:
+ - event: pull_request
+
# make sure api builds with default features (used by other crates relying on lemmy api)
check_api_common_default_features:
image: *rust_image
@@ -138,15 +168,6 @@ steps:
- diff tmp.schema crates/db_schema/src/schema.rs
when: *slow_check_paths
- cargo_clippy:
- image: *rust_image
- environment:
- CARGO_HOME: .cargo_home
- commands:
- - rustup component add clippy
- - cargo clippy --workspace --tests --all-targets -- -D warnings
- when: *slow_check_paths
-
cargo_build:
image: *rust_image
environment:
@@ -156,27 +177,6 @@ steps:
- mv target/debug/lemmy_server target/lemmy_server
when: *slow_check_paths
- cargo_test:
- image: *rust_image
- environment:
- LEMMY_DATABASE_URL: postgres://lemmy:password@database:5432/lemmy
- RUST_BACKTRACE: "1"
- CARGO_HOME: .cargo_home
- LEMMY_TEST_FAST_FEDERATION: "1"
- LEMMY_CONFIG_LOCATION: ../../config/config.hjson
- commands:
- - cargo test --workspace --no-fail-fast
- when: *slow_check_paths
-
- check_ts_bindings:
- image: *rust_image
- environment:
- CARGO_HOME: .cargo_home
- commands:
- - ./scripts/ts_bindings_check.sh
- when:
- - event: pull_request
-
check_diesel_migration:
# TODO: use willsquire/diesel-cli image when shared libraries become optional in lemmy_server
image: *rust_image
diff --git a/Cargo.lock b/Cargo.lock
index decdf74a5..669626caa 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1,6 +1,6 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
-version = 3
+version = 4
[[package]]
name = "accept-language"
@@ -779,17 +779,6 @@ dependencies = [
"nom",
]
-[[package]]
-name = "cfb"
-version = "0.7.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d38f2da7a0a2c4ccf0065be06397cc26a81f4e528be095826eee9d4adbb8c60f"
-dependencies = [
- "byteorder",
- "fnv",
- "uuid",
-]
-
[[package]]
name = "cfg-if"
version = "1.0.0"
@@ -2358,15 +2347,6 @@ dependencies = [
"serde",
]
-[[package]]
-name = "infer"
-version = "0.16.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bc150e5ce2330295b8616ce0e3f53250e53af31759a9dbedad1621ba29151847"
-dependencies = [
- "cfb",
-]
-
[[package]]
name = "inout"
version = "0.1.3"
@@ -2527,8 +2507,6 @@ dependencies = [
"encoding_rs",
"enum-map",
"futures",
- "getrandom",
- "infer",
"jsonwebtoken",
"lemmy_db_schema",
"lemmy_db_views",
@@ -2536,6 +2514,7 @@ dependencies = [
"lemmy_db_views_moderator",
"lemmy_utils",
"mime",
+ "mime_guess",
"moka",
"pretty_assertions",
"regex",
@@ -2603,6 +2582,7 @@ dependencies = [
"moka",
"pretty_assertions",
"reqwest 0.12.8",
+ "semver",
"serde",
"serde_json",
"serde_with",
@@ -3167,6 +3147,16 @@ version = "0.3.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
+[[package]]
+name = "mime_guess"
+version = "2.0.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f7c44f8e672c00fe5308fa235f821cb4198414e1c77935c1ab6948d3fd78550e"
+dependencies = [
+ "mime",
+ "unicase",
+]
+
[[package]]
name = "minimal-lexical"
version = "0.2.1"
@@ -5320,6 +5310,12 @@ version = "1.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
+[[package]]
+name = "unicase"
+version = "2.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7e51b68083f157f853b6379db119d1c1be0e6e4dec98101079dec41f6f5cf6df"
+
[[package]]
name = "unicode-bidi"
version = "0.3.15"
diff --git a/Cargo.toml b/Cargo.toml
index bce88af67..b1553be5c 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -131,7 +131,7 @@ chrono = { version = "0.4.38", features = [
], default-features = false }
serde_json = { version = "1.0.132", features = ["preserve_order"] }
base64 = "0.22.1"
-uuid = { version = "1.11.0", features = ["serde", "v4"] }
+uuid = { version = "1.11.0", features = ["serde"] }
async-trait = "0.1.83"
captcha = "0.0.9"
anyhow = { version = "1.0.93", features = [
diff --git a/api_tests/src/image.spec.ts b/api_tests/src/image.spec.ts
index ed96451a2..7ac6e7221 100644
--- a/api_tests/src/image.spec.ts
+++ b/api_tests/src/image.spec.ts
@@ -41,6 +41,9 @@ afterAll(async () => {
});
test("Upload image and delete it", async () => {
+ const healthz = await fetch(alphaUrl + "/pictrs/healthz");
+ expect(healthz.status).toBe(200);
+
// Before running this test, you need to delete all previous images in the DB
await deleteAllImages(alpha);
diff --git a/crates/api_common/Cargo.toml b/crates/api_common/Cargo.toml
index c5334edfc..5c41e4634 100644
--- a/crates/api_common/Cargo.toml
+++ b/crates/api_common/Cargo.toml
@@ -36,6 +36,7 @@ full = [
"futures",
"jsonwebtoken",
"mime",
+ "moka",
]
[dependencies]
@@ -58,7 +59,7 @@ uuid = { workspace = true, optional = true }
tokio = { workspace = true, optional = true }
reqwest = { workspace = true, optional = true }
ts-rs = { workspace = true, optional = true }
-moka.workspace = true
+moka = { workspace = true, optional = true }
anyhow.workspace = true
actix-web = { workspace = true, optional = true }
enum-map = { workspace = true }
@@ -70,11 +71,6 @@ webpage = { version = "2.0", default-features = false, features = [
], optional = true }
encoding_rs = { version = "0.8.35", optional = true }
jsonwebtoken = { version = "9.3.0", optional = true }
-# necessary for wasmt compilation
-getrandom = { version = "0.2.15", features = ["js"] }
-
-[package.metadata.cargo-shear]
-ignored = ["getrandom"]
[dev-dependencies]
serial_test = { workspace = true }
diff --git a/crates/apub/Cargo.toml b/crates/apub/Cargo.toml
index 057e9bd38..8124fda01 100644
--- a/crates/apub/Cargo.toml
+++ b/crates/apub/Cargo.toml
@@ -45,6 +45,7 @@ html2md = "0.2.14"
html2text = "0.12.6"
stringreader = "0.1.1"
enum_delegate = "0.2.0"
+semver = "1.0.23"
[dev-dependencies]
serial_test = { workspace = true }
diff --git a/crates/apub/assets/lemmy/activities/create_or_update/create_note.json b/crates/apub/assets/lemmy/activities/create_or_update/create_comment.json
similarity index 100%
rename from crates/apub/assets/lemmy/activities/create_or_update/create_note.json
rename to crates/apub/assets/lemmy/activities/create_or_update/create_comment.json
diff --git a/crates/apub/assets/lemmy/activities/create_or_update/create_private_message.json b/crates/apub/assets/lemmy/activities/create_or_update/create_private_message.json
index 54ee39350..e7dbdd0f9 100644
--- a/crates/apub/assets/lemmy/activities/create_or_update/create_private_message.json
+++ b/crates/apub/assets/lemmy/activities/create_or_update/create_private_message.json
@@ -3,7 +3,7 @@
"actor": "http://enterprise.lemmy.ml/u/lemmy_beta",
"to": ["http://ds9.lemmy.ml/u/lemmy_alpha"],
"object": {
- "type": "ChatMessage",
+ "type": "Note",
"id": "http://enterprise.lemmy.ml/private_message/1",
"attributedTo": "http://enterprise.lemmy.ml/u/lemmy_beta",
"to": ["http://ds9.lemmy.ml/u/lemmy_alpha"],
diff --git a/crates/apub/assets/lemmy/objects/note.json b/crates/apub/assets/lemmy/objects/comment.json
similarity index 100%
rename from crates/apub/assets/lemmy/objects/note.json
rename to crates/apub/assets/lemmy/objects/comment.json
diff --git a/crates/apub/assets/lemmy/objects/chat_message.json b/crates/apub/assets/lemmy/objects/private_message.json
similarity index 93%
rename from crates/apub/assets/lemmy/objects/chat_message.json
rename to crates/apub/assets/lemmy/objects/private_message.json
index 95b37322e..a3579523e 100644
--- a/crates/apub/assets/lemmy/objects/chat_message.json
+++ b/crates/apub/assets/lemmy/objects/private_message.json
@@ -1,6 +1,6 @@
{
"id": "https://enterprise.lemmy.ml/private_message/1621",
- "type": "ChatMessage",
+ "type": "Note",
"attributedTo": "https://enterprise.lemmy.ml/u/picard",
"to": ["https://queer.hacktivis.me/users/lanodan"],
"content": "
Hello hello, testing
\n",
diff --git a/crates/apub/assets/mastodon/activities/private_message.json b/crates/apub/assets/mastodon/activities/private_message.json
new file mode 100644
index 000000000..b542859b5
--- /dev/null
+++ b/crates/apub/assets/mastodon/activities/private_message.json
@@ -0,0 +1,49 @@
+{
+ "@context": [
+ "https://www.w3.org/ns/activitystreams",
+ {
+ "ostatus": "http://ostatus.org#",
+ "atomUri": "ostatus:atomUri",
+ "inReplyToAtomUri": "ostatus:inReplyToAtomUri",
+ "conversation": "ostatus:conversation",
+ "sensitive": "as:sensitive",
+ "toot": "http://joinmastodon.org/ns#",
+ "votersCount": "toot:votersCount"
+ }
+ ],
+ "id": "https://mastodon.world/users/nutomic/statuses/110854468010322301",
+ "type": "Note",
+ "summary": null,
+ "inReplyTo": "https://mastodon.world/users/nutomic/statuses/110854464248188528",
+ "published": "2023-08-08T14:29:04Z",
+ "url": "https://mastodon.world/@nutomic/110854468010322301",
+ "attributedTo": "https://mastodon.world/users/nutomic",
+ "to": ["https://ds9.lemmy.ml/u/nutomic"],
+ "cc": [],
+ "sensitive": false,
+ "atomUri": "https://mastodon.world/users/nutomic/statuses/110854468010322301",
+ "inReplyToAtomUri": "https://mastodon.world/users/nutomic/statuses/110854464248188528",
+ "conversation": "tag:mastodon.world,2023-08-08:objectId=121377096:objectType=Conversation",
+ "content": "@nutomic@ds9.lemmy.ml 444
",
+ "contentMap": {
+ "es": "@nutomic@ds9.lemmy.ml 444
"
+ },
+ "attachment": [],
+ "tag": [
+ {
+ "type": "Mention",
+ "href": "https://ds9.lemmy.ml/u/nutomic",
+ "name": "@nutomic@ds9.lemmy.ml"
+ }
+ ],
+ "replies": {
+ "id": "https://mastodon.world/users/nutomic/statuses/110854468010322301/replies",
+ "type": "Collection",
+ "first": {
+ "type": "CollectionPage",
+ "next": "https://mastodon.world/users/nutomic/statuses/110854468010322301/replies?only_other_accounts=true&page=true",
+ "partOf": "https://mastodon.world/users/nutomic/statuses/110854468010322301/replies",
+ "items": []
+ }
+ }
+}
diff --git a/crates/apub/assets/pleroma/objects/chat_message.json b/crates/apub/assets/pleroma/objects/chat_message.json
deleted file mode 100644
index 6a2afc82e..000000000
--- a/crates/apub/assets/pleroma/objects/chat_message.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "@context": [
- "https://www.w3.org/ns/activitystreams",
- "https://queer.hacktivis.me/schemas/litepub-0.1.jsonld",
- {
- "@language": "und"
- }
- ],
- "attributedTo": "https://queer.hacktivis.me/users/lanodan",
- "content": "Hi!",
- "id": "https://queer.hacktivis.me/objects/2",
- "published": "2020-02-12T14:08:20Z",
- "to": ["https://enterprise.lemmy.ml/u/picard"],
- "type": "ChatMessage"
-}
diff --git a/crates/apub/src/activities/community/announce.rs b/crates/apub/src/activities/community/announce.rs
index 950f4861d..9d714e304 100644
--- a/crates/apub/src/activities/community/announce.rs
+++ b/crates/apub/src/activities/community/announce.rs
@@ -64,16 +64,17 @@ impl ActivityHandler for RawAnnouncableActivities {
// verify and receive activity
activity.verify(context).await?;
- activity.clone().receive(context).await?;
+ let actor_id = activity.actor().clone().into();
+ activity.receive(context).await?;
// if community is local, send activity to followers
if let Some(community) = community {
if community.local {
- let actor_id = activity.actor().clone().into();
verify_person_in_community(&actor_id, &community, context).await?;
AnnounceActivity::send(self, &community, context).await?;
}
}
+
Ok(())
}
}
diff --git a/crates/apub/src/activities/create_or_update/comment.rs b/crates/apub/src/activities/create_or_update/comment.rs
index 9f64e805b..93cac92ee 100644
--- a/crates/apub/src/activities/create_or_update/comment.rs
+++ b/crates/apub/src/activities/create_or_update/comment.rs
@@ -43,6 +43,7 @@ use lemmy_utils::{
error::{LemmyError, LemmyResult},
utils::mention::scrape_text_for_mentions,
};
+use serde_json::{from_value, to_value};
use url::Url;
impl CreateOrUpdateNote {
@@ -98,7 +99,8 @@ impl CreateOrUpdateNote {
inboxes.add_inbox(person.shared_inbox_or_inbox());
}
- let activity = AnnouncableActivities::CreateOrUpdateComment(create_or_update);
+ let activity =
+ AnnouncableActivities::CreateOrUpdateNoteWrapper(from_value(to_value(create_or_update)?)?);
send_activity_in_community(activity, &person, &community, inboxes, false, &context).await
}
}
diff --git a/crates/apub/src/activities/create_or_update/mod.rs b/crates/apub/src/activities/create_or_update/mod.rs
index c69e00e91..b442e5fa3 100644
--- a/crates/apub/src/activities/create_or_update/mod.rs
+++ b/crates/apub/src/activities/create_or_update/mod.rs
@@ -1,3 +1,4 @@
pub mod comment;
+pub(crate) mod note_wrapper;
pub mod post;
pub mod private_message;
diff --git a/crates/apub/src/activities/create_or_update/note_wrapper.rs b/crates/apub/src/activities/create_or_update/note_wrapper.rs
new file mode 100644
index 000000000..9206d0c05
--- /dev/null
+++ b/crates/apub/src/activities/create_or_update/note_wrapper.rs
@@ -0,0 +1,66 @@
+use crate::{
+ objects::{community::ApubCommunity, note_wrapper::is_public},
+ protocol::{
+ activities::create_or_update::{
+ note::CreateOrUpdateNote,
+ note_wrapper::CreateOrUpdateNoteWrapper,
+ private_message::CreateOrUpdatePrivateMessage,
+ },
+ InCommunity,
+ },
+};
+use activitypub_federation::{config::Data, traits::ActivityHandler};
+use lemmy_api_common::context::LemmyContext;
+use lemmy_utils::error::{FederationError, LemmyError, LemmyResult};
+use serde_json::{from_value, to_value};
+use url::Url;
+
+#[async_trait::async_trait]
+impl ActivityHandler for CreateOrUpdateNoteWrapper {
+ type DataType = LemmyContext;
+ type Error = LemmyError;
+
+ fn id(&self) -> &Url {
+ &self.id
+ }
+
+ fn actor(&self) -> &Url {
+ &self.actor
+ }
+
+ #[tracing::instrument(skip_all)]
+ async fn verify(&self, context: &Data) -> LemmyResult<()> {
+ let val = to_value(self)?;
+ if is_public(&self.to, &self.cc) {
+ CreateOrUpdateNote::verify(&from_value(val)?, context).await?;
+ } else {
+ CreateOrUpdatePrivateMessage::verify(&from_value(val)?, context).await?;
+ }
+ Ok(())
+ }
+
+ #[tracing::instrument(skip_all)]
+ async fn receive(self, context: &Data) -> LemmyResult<()> {
+ let is_public = is_public(&self.to, &self.cc);
+ let val = to_value(self)?;
+ if is_public {
+ CreateOrUpdateNote::receive(from_value(val)?, context).await?;
+ } else {
+ CreateOrUpdatePrivateMessage::receive(from_value(val)?, context).await?;
+ }
+ Ok(())
+ }
+}
+
+#[async_trait::async_trait]
+impl InCommunity for CreateOrUpdateNoteWrapper {
+ #[tracing::instrument(skip(self, context))]
+ async fn community(&self, context: &Data) -> LemmyResult {
+ if is_public(&self.to, &self.cc) {
+ let comment: CreateOrUpdateNote = from_value(to_value(self)?)?;
+ comment.community(context).await
+ } else {
+ Err(FederationError::ObjectIsNotPublic.into())
+ }
+ }
+}
diff --git a/crates/apub/src/activities/create_or_update/private_message.rs b/crates/apub/src/activities/create_or_update/private_message.rs
index 6bba4e374..b6e7478ef 100644
--- a/crates/apub/src/activities/create_or_update/private_message.rs
+++ b/crates/apub/src/activities/create_or_update/private_message.rs
@@ -3,7 +3,7 @@ use crate::{
insert_received_activity,
objects::{person::ApubPerson, private_message::ApubPrivateMessage},
protocol::activities::{
- create_or_update::chat_message::CreateOrUpdateChatMessage,
+ create_or_update::private_message::CreateOrUpdatePrivateMessage,
CreateOrUpdateType,
},
};
@@ -30,7 +30,7 @@ pub(crate) async fn send_create_or_update_pm(
kind.clone(),
&context.settings().get_protocol_and_hostname(),
)?;
- let create_or_update = CreateOrUpdateChatMessage {
+ let create_or_update = CreateOrUpdatePrivateMessage {
id: id.clone(),
actor: actor.id().into(),
to: [recipient.id().into()],
@@ -44,7 +44,7 @@ pub(crate) async fn send_create_or_update_pm(
}
#[async_trait::async_trait]
-impl ActivityHandler for CreateOrUpdateChatMessage {
+impl ActivityHandler for CreateOrUpdatePrivateMessage {
type DataType = LemmyContext;
type Error = LemmyError;
diff --git a/crates/apub/src/activities/deletion/mod.rs b/crates/apub/src/activities/deletion/mod.rs
index 15118a476..941ac4237 100644
--- a/crates/apub/src/activities/deletion/mod.rs
+++ b/crates/apub/src/activities/deletion/mod.rs
@@ -36,7 +36,7 @@ use lemmy_db_schema::{
community::{Community, CommunityUpdateForm},
person::Person,
post::{Post, PostUpdateForm},
- private_message::{PrivateMessage, PrivateMessageUpdateForm},
+ private_message::{PrivateMessage as DbPrivateMessage, PrivateMessageUpdateForm},
},
traits::Crud,
};
@@ -82,7 +82,7 @@ pub(crate) async fn send_apub_delete_in_community(
#[tracing::instrument(skip_all)]
pub(crate) async fn send_apub_delete_private_message(
actor: &ApubPerson,
- pm: PrivateMessage,
+ pm: DbPrivateMessage,
deleted: bool,
context: Data,
) -> LemmyResult<()> {
@@ -298,7 +298,7 @@ async fn receive_delete_action(
}
}
DeletableObjects::PrivateMessage(pm) => {
- PrivateMessage::update(
+ DbPrivateMessage::update(
&mut context.pool(),
pm.id,
&PrivateMessageUpdateForm {
diff --git a/crates/apub/src/activity_lists.rs b/crates/apub/src/activity_lists.rs
index 7ed1d8baf..0a11e30a0 100644
--- a/crates/apub/src/activity_lists.rs
+++ b/crates/apub/src/activity_lists.rs
@@ -11,11 +11,7 @@ use crate::{
report::Report,
update::UpdateCommunity,
},
- create_or_update::{
- chat_message::CreateOrUpdateChatMessage,
- note::CreateOrUpdateNote,
- page::CreateOrUpdatePage,
- },
+ create_or_update::{note_wrapper::CreateOrUpdateNoteWrapper, page::CreateOrUpdatePage},
deletion::{delete::Delete, undo_delete::UndoDelete},
following::{
accept::AcceptFollow,
@@ -48,47 +44,17 @@ pub enum SharedInboxActivities {
AcceptFollow(AcceptFollow),
RejectFollow(RejectFollow),
UndoFollow(UndoFollow),
- CreateOrUpdatePrivateMessage(CreateOrUpdateChatMessage),
Report(Report),
AnnounceActivity(AnnounceActivity),
/// This is a catch-all and needs to be last
RawAnnouncableActivities(RawAnnouncableActivities),
}
-/// List of activities which the group inbox can handle.
-#[derive(Debug, Deserialize, Serialize)]
-#[serde(untagged)]
-#[enum_delegate::implement(ActivityHandler)]
-pub enum GroupInboxActivities {
- Follow(Follow),
- UndoFollow(UndoFollow),
- Report(Report),
- /// This is a catch-all and needs to be last
- AnnouncableActivities(RawAnnouncableActivities),
-}
-
-/// List of activities which the person inbox can handle.
-#[derive(Clone, Debug, Deserialize, Serialize)]
-#[serde(untagged)]
-#[enum_delegate::implement(ActivityHandler)]
-pub enum PersonInboxActivities {
- Follow(Follow),
- AcceptFollow(AcceptFollow),
- RejectFollow(RejectFollow),
- UndoFollow(UndoFollow),
- CreateOrUpdatePrivateMessage(CreateOrUpdateChatMessage),
- Delete(Delete),
- UndoDelete(UndoDelete),
- AnnounceActivity(AnnounceActivity),
- /// User can also receive some "announcable" activities, eg a comment mention.
- AnnouncableActivities(AnnouncableActivities),
-}
-
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(untagged)]
#[enum_delegate::implement(ActivityHandler)]
pub enum AnnouncableActivities {
- CreateOrUpdateComment(CreateOrUpdateNote),
+ CreateOrUpdateNoteWrapper(CreateOrUpdateNoteWrapper),
CreateOrUpdatePost(CreateOrUpdatePage),
Vote(Vote),
UndoVote(UndoVote),
@@ -111,7 +77,7 @@ impl InCommunity for AnnouncableActivities {
async fn community(&self, context: &Data) -> LemmyResult {
use AnnouncableActivities::*;
match self {
- CreateOrUpdateComment(a) => a.community(context).await,
+ CreateOrUpdateNoteWrapper(a) => a.community(context).await,
CreateOrUpdatePost(a) => a.community(context).await,
Vote(a) => a.community(context).await,
UndoVote(a) => a.community(context).await,
@@ -133,40 +99,32 @@ impl InCommunity for AnnouncableActivities {
mod tests {
use crate::{
- activity_lists::{GroupInboxActivities, PersonInboxActivities, SharedInboxActivities},
+ activity_lists::SharedInboxActivities,
protocol::tests::{test_json, test_parse_lemmy_item},
};
use lemmy_utils::error::LemmyResult;
- #[test]
- fn test_group_inbox() -> LemmyResult<()> {
- test_parse_lemmy_item::("assets/lemmy/activities/following/follow.json")?;
- test_parse_lemmy_item::(
- "assets/lemmy/activities/create_or_update/create_note.json",
- )?;
- Ok(())
- }
-
- #[test]
- fn test_person_inbox() -> LemmyResult<()> {
- test_parse_lemmy_item::(
- "assets/lemmy/activities/following/accept.json",
- )?;
- test_parse_lemmy_item::(
- "assets/lemmy/activities/create_or_update/create_note.json",
- )?;
- test_parse_lemmy_item::(
- "assets/lemmy/activities/create_or_update/create_private_message.json",
- )?;
- test_json::("assets/mastodon/activities/follow.json")?;
- Ok(())
- }
-
#[test]
fn test_shared_inbox() -> LemmyResult<()> {
test_parse_lemmy_item::(
"assets/lemmy/activities/deletion/delete_user.json",
)?;
+ test_parse_lemmy_item::(
+ "assets/lemmy/activities/following/accept.json",
+ )?;
+ test_parse_lemmy_item::(
+ "assets/lemmy/activities/create_or_update/create_comment.json",
+ )?;
+ test_parse_lemmy_item::(
+ "assets/lemmy/activities/create_or_update/create_private_message.json",
+ )?;
+ test_parse_lemmy_item::(
+ "assets/lemmy/activities/following/follow.json",
+ )?;
+ test_parse_lemmy_item::(
+ "assets/lemmy/activities/create_or_update/create_comment.json",
+ )?;
+ test_json::("assets/mastodon/activities/follow.json")?;
Ok(())
}
}
diff --git a/crates/apub/src/objects/comment.rs b/crates/apub/src/objects/comment.rs
index dc0721404..2c8ed9f9d 100644
--- a/crates/apub/src/objects/comment.rs
+++ b/crates/apub/src/objects/comment.rs
@@ -266,7 +266,7 @@ pub(crate) mod tests {
let url = Url::parse("https://enterprise.lemmy.ml/comment/38741")?;
let data = prepare_comment_test(&url, &context).await?;
- let json: Note = file_to_json_object("assets/lemmy/objects/note.json")?;
+ let json: Note = file_to_json_object("assets/lemmy/objects/comment.json")?;
ApubComment::verify(&json, &url, &context).await?;
let comment = ApubComment::from_json(json.clone(), &context).await?;
diff --git a/crates/apub/src/objects/mod.rs b/crates/apub/src/objects/mod.rs
index f837f7ad3..58841b29e 100644
--- a/crates/apub/src/objects/mod.rs
+++ b/crates/apub/src/objects/mod.rs
@@ -15,6 +15,7 @@ use std::fmt::Debug;
pub mod comment;
pub mod community;
pub mod instance;
+pub mod note_wrapper;
pub mod person;
pub mod post;
pub mod private_message;
diff --git a/crates/apub/src/objects/note_wrapper.rs b/crates/apub/src/objects/note_wrapper.rs
new file mode 100644
index 000000000..5d613c7ae
--- /dev/null
+++ b/crates/apub/src/objects/note_wrapper.rs
@@ -0,0 +1,85 @@
+use super::comment::ApubComment;
+use crate::{
+ objects::private_message::ApubPrivateMessage,
+ protocol::objects::note_wrapper::NoteWrapper,
+};
+use activitypub_federation::{config::Data, kinds::public, traits::Object};
+use chrono::{DateTime, Utc};
+use lemmy_api_common::{context::LemmyContext, LemmyErrorType};
+use lemmy_utils::error::{LemmyError, LemmyResult};
+use serde_json::{from_value, to_value};
+use url::Url;
+
+/// Private messages and public comments are quite awkward in Activitypub, because the json
+/// format looks identical. They only way to differentiate them is to check for the presence
+/// or absence of `https://www.w3.org/ns/activitystreams#Public` in `to` or `cc` which this
+/// wrapper does.
+#[derive(Debug)]
+pub(crate) struct ApubNote {}
+
+#[async_trait::async_trait]
+impl Object for ApubNote {
+ type DataType = LemmyContext;
+ type Kind = NoteWrapper;
+ type Error = LemmyError;
+
+ fn last_refreshed_at(&self) -> Option> {
+ None
+ }
+
+ #[tracing::instrument(skip_all)]
+ async fn read_from_id(
+ _object_id: Url,
+ _context: &Data,
+ ) -> LemmyResult