diff --git a/api_tests/src/private_message.spec.ts b/api_tests/src/private_message.spec.ts index 5c18f93efb..dab1dd57aa 100644 --- a/api_tests/src/private_message.spec.ts +++ b/api_tests/src/private_message.spec.ts @@ -1,5 +1,9 @@ jest.setTimeout(120000); -import { LemmyError, PrivateMessageView } from "lemmy-js-client"; +import { + LemmyError, + PrivateMessageReportView, + PrivateMessageView, +} from "lemmy-js-client"; import { alpha, beta, @@ -16,6 +20,7 @@ import { expectSuccess, waitUntilSuccess, expectFailure, + listReports, } from "./shared"; let recipient_id: number; @@ -165,4 +170,17 @@ test("Create a private message report", async () => { expect(report.private_message_report_view.private_message_report.reason).toBe( reason, ); + + const list_reports = ( + await waitUntilSuccess( + () => listReports(alpha), + r => r.items.some(r => r.type_ === "private_message"), + ) + ).items.filter(r => r.type_ === "private_message"); + + const r = list_reports[0] as PrivateMessageReportView; + expect(r.private_message.ap_id).toBe(betaPm.private_message.ap_id); + expect(r.private_message.content).toBe(betaPm.private_message.content); + expect(r.private_message_creator.ap_id).toBe(betaPm.creator.ap_id); + expect(r.private_message_report.reason).toBe(reason); }); diff --git a/crates/api/api/src/reports/private_message_report/create.rs b/crates/api/api/src/reports/private_message_report/create.rs index ac27b65e5e..7d62552840 100644 --- a/crates/api/api/src/reports/private_message_report/create.rs +++ b/crates/api/api/src/reports/private_message_report/create.rs @@ -1,14 +1,18 @@ use crate::check_report_reason; -use actix_web::web::{Data, Json}; +use activitypub_federation::config::Data; +use actix_web::web::Json; +use either::Either; use lemmy_api_utils::{ context::LemmyContext, plugins::plugin_hook_after, + send_activity::{ActivityChannel, SendActivityData}, utils::{check_local_user_banned_or_deleted, slur_regex}, }; use lemmy_db_schema::{ source::{ private_message::PrivateMessage, private_message_report::{PrivateMessageReport, PrivateMessageReportForm}, + site::Site, }, traits::Reportable, }; @@ -70,7 +74,26 @@ pub async fn create_pm_report( .await?; } - // TODO: consider federating this + let site = Site::read_from_instance_id( + &mut context.pool(), + private_message_report_view + .private_message_creator + .instance_id, + ) + .await?; + ActivityChannel::submit_activity( + SendActivityData::CreateReport { + object_id: private_message_report_view + .private_message + .ap_id + .inner() + .clone(), + actor: private_message_report_view.creator.clone(), + receiver: Either::Left(site), + reason: data.reason.clone(), + }, + &context, + )?; Ok(Json(PrivateMessageReportResponse { private_message_report_view, diff --git a/crates/api/api/src/reports/private_message_report/resolve.rs b/crates/api/api/src/reports/private_message_report/resolve.rs index 2544700ee4..083bec2106 100644 --- a/crates/api/api/src/reports/private_message_report/resolve.rs +++ b/crates/api/api/src/reports/private_message_report/resolve.rs @@ -1,11 +1,21 @@ -use actix_web::web::{Data, Json}; -use lemmy_api_utils::{context::LemmyContext, utils::is_admin}; -use lemmy_db_schema::{source::private_message_report::PrivateMessageReport, traits::Reportable}; +use activitypub_federation::config::Data; +use actix_web::web::Json; +use either::Either; +use lemmy_api_utils::{ + context::LemmyContext, + send_activity::{ActivityChannel, SendActivityData}, + utils::is_admin, +}; +use lemmy_db_schema::{ + source::{person::Person, private_message_report::PrivateMessageReport, site::Site}, + traits::Reportable, +}; use lemmy_db_views_local_user::LocalUserView; use lemmy_db_views_report_combined::{ ReportCombinedViewInternal, api::{PrivateMessageReportResponse, ResolvePrivateMessageReport}, }; +use lemmy_diesel_utils::traits::Crud; use lemmy_utils::error::LemmyResult; pub async fn resolve_pm_report( @@ -24,6 +34,26 @@ pub async fn resolve_pm_report( ReportCombinedViewInternal::read_private_message_report(&mut context.pool(), report_id, person) .await?; + let recipient = Person::read( + &mut context.pool(), + private_message_report_view.private_message.recipient_id, + ) + .await?; + let site = Site::read_from_instance_id(&mut context.pool(), recipient.instance_id).await?; + ActivityChannel::submit_activity( + SendActivityData::SendResolveReport { + object_id: private_message_report_view + .private_message + .ap_id + .inner() + .clone(), + actor: local_user_view.person, + report_creator: private_message_report_view.creator.clone(), + receiver: Either::Left(site), + }, + &context, + )?; + Ok(Json(PrivateMessageReportResponse { private_message_report_view, })) diff --git a/crates/apub/activities/src/community/report.rs b/crates/apub/activities/src/community/report.rs index b6592561bb..0f04bcbfb5 100644 --- a/crates/apub/activities/src/community/report.rs +++ b/crates/apub/activities/src/community/report.rs @@ -41,6 +41,7 @@ use lemmy_db_schema::{ community_report::{CommunityReport, CommunityReportForm}, post::Post, post_report::{PostReport, PostReportForm}, + private_message_report::{PrivateMessageReport, PrivateMessageReportForm}, }, traits::Reportable, }; @@ -118,9 +119,10 @@ impl Activity for Report { check_community_deleted_or_removed(&community)?; check_comment_deleted_or_removed(&comment)?; } - ReportableObjects::Right(community) => { + ReportableObjects::Right(Either::Left(community)) => { check_community_deleted_removed(&community)?; } + ReportableObjects::Right(Either::Right(_private_message)) => {} } Ok(()) } @@ -151,7 +153,7 @@ impl Activity for Report { }; CommentReport::report(&mut context.pool(), &report_form).await?; } - ReportableObjects::Right(community) => { + ReportableObjects::Right(Either::Left(community)) => { let report_form = CommunityReportForm { creator_id: actor.id, community_id: community.id, @@ -165,6 +167,15 @@ impl Activity for Report { }; CommunityReport::report(&mut context.pool(), &report_form).await?; } + ReportableObjects::Right(Either::Right(private_message)) => { + let form = PrivateMessageReportForm { + creator_id: actor.id, + private_message_id: private_message.id, + original_pm_text: private_message.content.clone(), + reason, + }; + PrivateMessageReport::report(&mut context.pool(), &form).await?; + } }; let receiver = self.to[0].dereference(context).await?; diff --git a/crates/apub/activities/src/community/resolve_report.rs b/crates/apub/activities/src/community/resolve_report.rs index 119c6fb41d..8d5e0b2134 100644 --- a/crates/apub/activities/src/community/resolve_report.rs +++ b/crates/apub/activities/src/community/resolve_report.rs @@ -32,6 +32,7 @@ use lemmy_db_schema::{ comment_report::CommentReport, community_report::CommunityReport, post_report::PostReport, + private_message_report::PrivateMessageReport, }, traits::Reportable, }; @@ -95,10 +96,19 @@ impl Activity for ResolveReport { ReportableObjects::Left(PostOrComment::Right(comment)) => { CommentReport::resolve_apub(&mut context.pool(), comment.id, reporter.id, actor.id).await?; } - ReportableObjects::Right(community) => { + ReportableObjects::Right(Either::Left(community)) => { CommunityReport::resolve_apub(&mut context.pool(), community.id, reporter.id, actor.id) .await?; } + ReportableObjects::Right(Either::Right(private_message)) => { + PrivateMessageReport::resolve_apub( + &mut context.pool(), + private_message.id, + reporter.id, + actor.id, + ) + .await?; + } }; let receiver = self.object.to[0].dereference(context).await?; diff --git a/crates/apub/objects/src/objects/mod.rs b/crates/apub/objects/src/objects/mod.rs index 0a0c6a1748..6e4f1069ea 100644 --- a/crates/apub/objects/src/objects/mod.rs +++ b/crates/apub/objects/src/objects/mod.rs @@ -7,6 +7,7 @@ pub mod person; pub mod post; pub mod private_message; +use crate::objects::private_message::ApubPrivateMessage; use comment::ApubComment; use community::ApubCommunity; use either::Either; @@ -21,7 +22,7 @@ pub type PostOrComment = Either; pub type SearchableObjects = Either, ApubMultiCommunity>; -pub type ReportableObjects = Either; +pub type ReportableObjects = Either>; pub type UserOrCommunity = Either; diff --git a/crates/db_schema/src/impls/private_message_report.rs b/crates/db_schema/src/impls/private_message_report.rs index 2502dac13a..5a5d58d2f0 100644 --- a/crates/db_schema/src/impls/private_message_report.rs +++ b/crates/db_schema/src/impls/private_message_report.rs @@ -5,6 +5,7 @@ use crate::{ }; use chrono::Utc; use diesel::{ + BoolExpressionMethods, ExpressionMethods, QueryDsl, dsl::{insert_into, update}, @@ -12,7 +13,7 @@ use diesel::{ use diesel_async::RunQueryDsl; use lemmy_db_schema_file::{PersonId, schema::private_message_report}; use lemmy_diesel_utils::connection::{DbPool, get_conn}; -use lemmy_utils::error::{LemmyErrorExt, LemmyErrorType, LemmyResult, UntranslatedError}; +use lemmy_utils::error::{LemmyErrorExt, LemmyErrorType, LemmyResult}; impl Reportable for PrivateMessageReport { type Form = PrivateMessageReportForm; @@ -46,12 +47,27 @@ impl Reportable for PrivateMessageReport { .with_lemmy_type(LemmyErrorType::CouldntUpdate) } async fn resolve_apub( - _pool: &mut DbPool<'_>, - _object_id: Self::ObjectIdType, - _report_creator_id: PersonId, - _resolver_id: PersonId, + pool: &mut DbPool<'_>, + object_id: Self::ObjectIdType, + report_creator_id: PersonId, + resolver_id: PersonId, ) -> LemmyResult { - Err(UntranslatedError::Unreachable.into()) + let conn = &mut get_conn(pool).await?; + update( + private_message_report::table.filter( + private_message_report::private_message_id + .eq(object_id) + .and(private_message_report::creator_id.eq(report_creator_id)), + ), + ) + .set(( + private_message_report::resolved.eq(true), + private_message_report::resolver_id.eq(resolver_id), + private_message_report::updated_at.eq(Utc::now()), + )) + .execute(conn) + .await + .with_lemmy_type(LemmyErrorType::CouldntUpdate) } // This is unused because private message doesn't have remove handler