2 activities::receive::verify_activity_domains_valid,
3 check_is_apub_id_valid,
4 fetcher::person::get_or_fetch_and_upsert_person,
5 inbox::get_activity_to_and_cc,
10 activity::{ActorAndObjectRefExt, Create, Delete, Undo, Update},
11 base::{AsBase, ExtendsExt},
15 use anyhow::{anyhow, Context};
16 use lemmy_api_common::{blocking, person::PrivateMessageResponse};
17 use lemmy_db_queries::source::private_message::PrivateMessage_;
18 use lemmy_db_schema::source::private_message::PrivateMessage;
19 use lemmy_db_views::{local_user_view::LocalUserView, private_message_view::PrivateMessageView};
20 use lemmy_utils::{location_info, LemmyError};
21 use lemmy_websocket::{messages::SendUserRoomMessage, LemmyContext, UserOperationCrud};
24 pub(crate) async fn receive_create_private_message(
25 context: &LemmyContext,
28 request_counter: &mut i32,
29 ) -> Result<(), LemmyError> {
30 check_private_message_activity_valid(&create, context, request_counter).await?;
32 let note = NoteExt::from_any_base(
36 .context(location_info!())?
39 .context(location_info!())?;
42 PrivateMessage::from_apub(¬e, context, expected_domain, request_counter, false).await?;
44 let message = blocking(&context.pool(), move |conn| {
45 PrivateMessageView::read(conn, private_message.id)
49 let res = PrivateMessageResponse {
50 private_message_view: message,
53 // Send notifications to the local recipient, if one exists
54 let recipient_id = res.private_message_view.recipient.id;
55 let local_recipient_id = blocking(context.pool(), move |conn| {
56 LocalUserView::read_person(conn, recipient_id)
62 context.chat_server().do_send(SendUserRoomMessage {
63 op: UserOperationCrud::CreatePrivateMessage,
72 pub(crate) async fn receive_update_private_message(
73 context: &LemmyContext,
76 request_counter: &mut i32,
77 ) -> Result<(), LemmyError> {
78 check_private_message_activity_valid(&update, context, request_counter).await?;
83 .context(location_info!())?
85 let note = NoteExt::from_any_base(object)?.context(location_info!())?;
88 PrivateMessage::from_apub(¬e, context, expected_domain, request_counter, false).await?;
90 let private_message_id = private_message.id;
91 let message = blocking(&context.pool(), move |conn| {
92 PrivateMessageView::read(conn, private_message_id)
96 let res = PrivateMessageResponse {
97 private_message_view: message,
100 let recipient_id = res.private_message_view.recipient.id;
101 let local_recipient_id = blocking(context.pool(), move |conn| {
102 LocalUserView::read_person(conn, recipient_id)
108 context.chat_server().do_send(SendUserRoomMessage {
109 op: UserOperationCrud::EditPrivateMessage,
118 pub(crate) async fn receive_delete_private_message(
119 context: &LemmyContext,
121 private_message: PrivateMessage,
122 request_counter: &mut i32,
123 ) -> Result<(), LemmyError> {
124 check_private_message_activity_valid(&delete, context, request_counter).await?;
126 let deleted_private_message = blocking(context.pool(), move |conn| {
127 PrivateMessage::update_deleted(conn, private_message.id, true)
131 let message = blocking(&context.pool(), move |conn| {
132 PrivateMessageView::read(&conn, deleted_private_message.id)
136 let res = PrivateMessageResponse {
137 private_message_view: message,
140 let recipient_id = res.private_message_view.recipient.id;
141 let local_recipient_id = blocking(context.pool(), move |conn| {
142 LocalUserView::read_person(conn, recipient_id)
148 context.chat_server().do_send(SendUserRoomMessage {
149 op: UserOperationCrud::EditPrivateMessage,
158 pub(crate) async fn receive_undo_delete_private_message(
159 context: &LemmyContext,
161 expected_domain: &Url,
162 private_message: PrivateMessage,
163 request_counter: &mut i32,
164 ) -> Result<(), LemmyError> {
165 check_private_message_activity_valid(&undo, context, request_counter).await?;
166 let object = undo.object().to_owned().one().context(location_info!())?;
167 let delete = Delete::from_any_base(object)?.context(location_info!())?;
168 verify_activity_domains_valid(&delete, expected_domain, true)?;
169 check_private_message_activity_valid(&delete, context, request_counter).await?;
171 let deleted_private_message = blocking(context.pool(), move |conn| {
172 PrivateMessage::update_deleted(conn, private_message.id, false)
176 let message = blocking(&context.pool(), move |conn| {
177 PrivateMessageView::read(&conn, deleted_private_message.id)
181 let res = PrivateMessageResponse {
182 private_message_view: message,
185 let recipient_id = res.private_message_view.recipient.id;
186 let local_recipient_id = blocking(context.pool(), move |conn| {
187 LocalUserView::read_person(conn, recipient_id)
193 context.chat_server().do_send(SendUserRoomMessage {
194 op: UserOperationCrud::EditPrivateMessage,
203 async fn check_private_message_activity_valid<T, Kind>(
205 context: &LemmyContext,
206 request_counter: &mut i32,
207 ) -> Result<(), LemmyError>
209 T: AsBase<Kind> + AsObject<Kind> + ActorAndObjectRefExt,
211 let to_and_cc = get_activity_to_and_cc(activity);
212 if to_and_cc.len() != 1 {
213 return Err(anyhow!("Private message can only be addressed to one person").into());
215 if to_and_cc.contains(&public()) {
216 return Err(anyhow!("Private message cant be public").into());
218 let person_id = activity
221 .single_xsd_any_uri()
222 .context(location_info!())?;
223 check_is_apub_id_valid(&person_id)?;
224 // check that the sender is a person, not a community
225 get_or_fetch_and_upsert_person(&person_id, &context, request_counter).await?;