Mention all recipients in subscribers-only posts

This commit is contained in:
silverpill 2022-06-15 12:08:53 +00:00
parent fd7ef7b9c1
commit 166a81ce6b
2 changed files with 39 additions and 9 deletions

View file

@ -15,6 +15,7 @@ use crate::errors::DatabaseError;
use crate::frontend::get_tag_page_url;
use crate::models::posts::queries::get_post_author;
use crate::models::posts::types::{Post, Visibility};
use crate::models::profiles::types::DbActorProfile;
use crate::models::relationships::queries::{get_followers, get_subscribers};
use crate::models::users::types::User;
use crate::utils::files::get_file_url;
@ -53,6 +54,7 @@ pub fn build_note(
instance_host: &str,
instance_url: &str,
post: &Post,
subscribers: Vec<DbActorProfile>,
) -> Note {
let object_id = get_object_url(
instance_url,
@ -103,6 +105,21 @@ pub fn build_note(
};
tags.push(tag);
};
if matches!(post.visibility, Visibility::Subscribers) {
// Mention all subscribers
// (for recipients that don't support subscribers-only posts)
for profile in subscribers {
let tag_name = format!("@{}", profile.actor_address(instance_host));
let actor_id = profile.actor_id(instance_url);
secondary_audience.push(actor_id.clone());
let tag = Tag {
name: Some(tag_name),
tag_type: MENTION.to_string(),
href: Some(actor_id),
};
tags.push(tag);
};
};
for tag_name in &post.tags {
let tag_page_url = get_tag_page_url(instance_url, tag_name);
let tag = Tag {
@ -143,8 +160,9 @@ pub fn build_create_note(
instance_host: &str,
instance_url: &str,
post: &Post,
subscribers: Vec<DbActorProfile>,
) -> Activity {
let object = build_note(instance_host, instance_url, post);
let object = build_note(instance_host, instance_url, post, subscribers);
let primary_audience = object.to.clone();
let secondary_audience = object.cc.clone();
let activity_id = format!("{}/create", object.id);
@ -200,10 +218,16 @@ pub async fn prepare_create_note(
post: &Post,
) -> Result<OutgoingActivity, DatabaseError> {
assert_eq!(author.id, post.author.id);
let subscribers = if matches!(post.visibility, Visibility::Subscribers) {
get_subscribers(db_client, &author.id).await?
} else {
vec![]
};
let activity = build_create_note(
&instance.host(),
&instance.url(),
post,
subscribers,
);
let recipients = get_note_recipients(db_client, author, post).await?;
Ok(OutgoingActivity {
@ -217,7 +241,6 @@ pub async fn prepare_create_note(
#[cfg(test)]
mod tests {
use serde_json::json;
use crate::models::profiles::types::DbActorProfile;
use super::*;
const INSTANCE_HOST: &str = "example.com";
@ -230,7 +253,7 @@ mod tests {
..Default::default()
};
let post = Post { author, ..Default::default() };
let note = build_note(INSTANCE_HOST, INSTANCE_URL, &post);
let note = build_note(INSTANCE_HOST, INSTANCE_URL, &post, vec![]);
assert_eq!(
note.id,
@ -255,7 +278,7 @@ mod tests {
visibility: Visibility::Followers,
..Default::default()
};
let note = build_note(INSTANCE_HOST, INSTANCE_URL, &post);
let note = build_note(INSTANCE_HOST, INSTANCE_URL, &post, vec![]);
assert_eq!(note.to, vec![
get_followers_url(INSTANCE_URL, &post.author.username),
@ -271,7 +294,7 @@ mod tests {
in_reply_to: Some(Box::new(parent.clone())),
..Default::default()
};
let note = build_note(INSTANCE_HOST, INSTANCE_URL, &post);
let note = build_note(INSTANCE_HOST, INSTANCE_URL, &post, vec![]);
assert_eq!(
note.in_reply_to.unwrap(),
@ -309,7 +332,7 @@ mod tests {
mentions: vec![parent_author],
..Default::default()
};
let note = build_note(INSTANCE_HOST, INSTANCE_URL, &post);
let note = build_note(INSTANCE_HOST, INSTANCE_URL, &post, vec![]);
assert_eq!(
note.in_reply_to.unwrap(),
@ -330,7 +353,12 @@ mod tests {
..Default::default()
};
let post = Post { author, ..Default::default() };
let activity = build_create_note(INSTANCE_HOST, INSTANCE_URL, &post);
let activity = build_create_note(
INSTANCE_HOST,
INSTANCE_URL,
&post,
vec![],
);
assert_eq!(
activity.id,

View file

@ -172,6 +172,7 @@ async fn outbox(
&instance.host(),
&instance.url(),
post,
vec![], // subscribers-only posts are not included
);
Some(activity)
}).collect();
@ -286,9 +287,9 @@ pub async fn object_view(
internal_object_id: web::Path<Uuid>,
) -> Result<HttpResponse, HttpError> {
let db_client = &**get_database_client(&db_pool).await?;
// Try to find local post by ID,
// return 404 if not found or if repost is found
let internal_object_id = internal_object_id.into_inner();
// Try to find local post by ID,
// return 404 if not found, or not public, or it is a repost
let thread = get_thread(db_client, &internal_object_id, None).await?;
let mut post = thread.iter()
.find(|post| post.id == internal_object_id && post.author.is_local())
@ -316,6 +317,7 @@ pub async fn object_view(
&config.instance().host(),
&config.instance().url(),
&post,
vec![], // subscribers-only posts are not accessible
);
let response = HttpResponse::Ok()
.content_type(ACTIVITY_CONTENT_TYPE)