Skip to content

Commit

Permalink
Merge branch 'LemmyNet:main' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
kroese authored Nov 4, 2024
2 parents 5b03045 + 4690aff commit 104f71d
Show file tree
Hide file tree
Showing 42 changed files with 389 additions and 316 deletions.
2 changes: 1 addition & 1 deletion .woodpecker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ steps:
when: *slow_check_paths

run_federation_tests:
image: node:20-bookworm-slim
image: node:22-bookworm-slim
environment:
LEMMY_DATABASE_URL: postgres://lemmy:password@database:5432
DO_WRITE_HOSTS_FILE: "1"
Expand Down
2 changes: 1 addition & 1 deletion api_tests/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"repository": "https://github.com/LemmyNet/lemmy",
"author": "Dessalines",
"license": "AGPL-3.0",
"packageManager": "[email protected].0",
"packageManager": "[email protected].3",
"scripts": {
"lint": "tsc --noEmit && eslint --report-unused-disable-directives && prettier --check 'src/**/*.ts'",
"fix": "prettier --write src && eslint --fix src",
Expand Down
436 changes: 188 additions & 248 deletions api_tests/pnpm-lock.yaml

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion api_tests/src/comment.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -860,7 +860,7 @@ test("Dont send a comment reply to a blocked community", async () => {

/// Fetching a deeply nested comment can lead to stack overflow as all parent comments are also
/// fetched recursively. Ensure that it works properly.
test("Fetch a deeply nested comment", async () => {
test.skip("Fetch a deeply nested comment", async () => {
let lastComment;
for (let i = 0; i < 50; i++) {
let commentRes = await createComment(
Expand Down
5 changes: 1 addition & 4 deletions crates/api/src/post/get_link_metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,7 @@ use lemmy_api_common::{
request::fetch_link_metadata,
};
use lemmy_db_views::structs::LocalUserView;
use lemmy_utils::{
error::{LemmyErrorExt, LemmyResult},
LemmyErrorType,
};
use lemmy_utils::error::{LemmyErrorExt, LemmyErrorType, LemmyResult};
use url::Url;

#[tracing::instrument(skip(context))]
Expand Down
5 changes: 4 additions & 1 deletion crates/api/src/site/registration_applications/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,10 @@ use lemmy_db_schema::{
RegistrationMode,
};
use lemmy_db_views::structs::LocalUserView;
use lemmy_utils::{error::LemmyResult, LemmyErrorType, CACHE_DURATION_API};
use lemmy_utils::{
error::{LemmyErrorType, LemmyResult},
CACHE_DURATION_API,
};
use serial_test::serial;

async fn create_test_site(context: &Data<LemmyContext>) -> LemmyResult<(Instance, LocalUserView)> {
Expand Down
6 changes: 3 additions & 3 deletions crates/api/src/sitemap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ async fn generate_urlset(
) -> LemmyResult<UrlSet> {
let urls = posts
.into_iter()
.map_while(|post| {
Url::builder(post.0.to_string())
.last_modified(post.1.into())
.map_while(|(url, date_time)| {
Url::builder(url.to_string())
.last_modified(date_time.into())
.build()
.ok()
})
Expand Down
2 changes: 1 addition & 1 deletion crates/api_common/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ pub extern crate lemmy_db_views_actor;
pub extern crate lemmy_db_views_moderator;
pub extern crate lemmy_utils;

pub use lemmy_utils::LemmyErrorType;
pub use lemmy_utils::error::LemmyErrorType;
use serde::{Deserialize, Serialize};
use std::{cmp::min, time::Duration};

Expand Down
2 changes: 1 addition & 1 deletion crates/api_common/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1110,7 +1110,7 @@ async fn proxy_image_link_internal(

/// Rewrite a link to go through `/api/v3/image_proxy` endpoint. This is only for remote urls and
/// if image_proxy setting is enabled.
pub(crate) async fn proxy_image_link(link: Url, context: &LemmyContext) -> LemmyResult<DbUrl> {
pub async fn proxy_image_link(link: Url, context: &LemmyContext) -> LemmyResult<DbUrl> {
proxy_image_link_internal(
link,
context.settings().pictrs_config()?.image_mode(),
Expand Down
2 changes: 1 addition & 1 deletion crates/api_crud/src/post/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use chrono::{DateTime, TimeZone, Utc};
use lemmy_api_common::context::LemmyContext;
use lemmy_db_schema::source::post::Post;
use lemmy_db_views::structs::LocalUserView;
use lemmy_utils::{error::LemmyResult, LemmyErrorType};
use lemmy_utils::error::{LemmyErrorType, LemmyResult};

pub mod create;
pub mod delete;
Expand Down
79 changes: 79 additions & 0 deletions crates/apub/assets/mastodon/objects/note_2.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
{
"@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",
"blurhash": "toot:blurhash",
"focalPoint": {
"@container": "@list",
"@id": "toot:focalPoint"
}
}
],
"id": "https://floss.social/users/kde/statuses/113306831140126616",
"type": "Note",
"summary": null,
"inReplyTo": "https://floss.social/users/kde/statuses/113306824627995724",
"published": "2024-10-14T16:57:15Z",
"url": "https://floss.social/@kde/113306831140126616",
"attributedTo": "https://floss.social/users/kde",
"to": ["https://www.w3.org/ns/activitystreams#Public"],
"cc": [
"https://floss.social/users/kde/followers",
"https://lemmy.kde.social/c/kde",
"https://lemmy.kde.social/c/kde/followers"
],
"sensitive": false,
"atomUri": "https://floss.social/users/kde/statuses/113306831140126616",
"inReplyToAtomUri": "https://floss.social/users/kde/statuses/113306824627995724",
"conversation": "tag:floss.social,2024-10-14:objectId=71424279:objectType=Conversation",
"content": "<p><span class=\"h-card\" translate=\"no\"><a href=\"https://lemmy.kde.social/c/kde\" class=\"u-url mention\">@<span>[email protected]</span></a></span> </p><p>We also need funding 💶 to keep the gears turning! Please support us with a donation:</p><p><a href=\"https://kde.org/donate/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" translate=\"no\"><span class=\"invisible\">https://</span><span class=\"\">kde.org/donate/</span><span class=\"invisible\"></span></a></p><p>[3/3]</p>",
"contentMap": {
"en": "<p><span class=\"h-card\" translate=\"no\"><a href=\"https://lemmy.kde.social/c/kde\" class=\"u-url mention\">@<span>[email protected]</span></a></span> </p><p>We also need funding 💶 to keep the gears turning! Please support us with a donation:</p><p><a href=\"https://kde.org/donate/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" translate=\"no\"><span class=\"invisible\">https://</span><span class=\"\">kde.org/donate/</span><span class=\"invisible\"></span></a></p><p>[3/3]</p>"
},
"attachment": [
{
"type": "Document",
"mediaType": "image/jpeg",
"url": "https://cdn.masto.host/floss/media_attachments/files/113/306/826/682/985/891/original/c8d906a2f2ab2334.jpg",
"name": "The KDE dragons Katie and Konqi stand on either side of a pot filling up with gold coins. Donate!",
"blurhash": "USQv:h-W-qI-^,W;RPs=^-R%NZxbo#sDobSc",
"focalPoint": [0.0, 0.0],
"width": 1500,
"height": 1095
}
],
"tag": [
{
"type": "Mention",
"href": "https://lemmy.kde.social/c/kde",
"name": "@[email protected]"
}
],
"replies": {
"id": "https://floss.social/users/kde/statuses/113306831140126616/replies",
"type": "Collection",
"first": {
"type": "CollectionPage",
"next": "https://floss.social/users/kde/statuses/113306831140126616/replies?only_other_accounts=true&page=true",
"partOf": "https://floss.social/users/kde/statuses/113306831140126616/replies",
"items": []
}
},
"likes": {
"id": "https://floss.social/users/kde/statuses/113306831140126616/likes",
"type": "Collection",
"totalItems": 39
},
"shares": {
"id": "https://floss.social/users/kde/statuses/113306831140126616/shares",
"type": "Collection",
"totalItems": 24
}
}
2 changes: 1 addition & 1 deletion crates/apub/src/activity_lists.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ use crate::{
};
use activitypub_federation::{config::Data, traits::ActivityHandler};
use lemmy_api_common::context::LemmyContext;
use lemmy_utils::{error::LemmyResult, LemmyErrorType};
use lemmy_utils::error::{LemmyErrorType, LemmyResult};
use serde::{Deserialize, Serialize};
use url::Url;

Expand Down
2 changes: 1 addition & 1 deletion crates/apub/src/api/resolve_object.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ mod tests {
traits::Crud,
};
use lemmy_db_views::structs::LocalUserView;
use lemmy_utils::{error::LemmyResult, LemmyErrorType};
use lemmy_utils::error::{LemmyErrorType, LemmyResult};
use serial_test::serial;

#[tokio::test]
Expand Down
2 changes: 1 addition & 1 deletion crates/apub/src/http/community.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use activitypub_federation::{
use actix_web::{web, HttpResponse};
use lemmy_api_common::context::LemmyContext;
use lemmy_db_schema::{source::community::Community, traits::ApubActor};
use lemmy_utils::{error::LemmyResult, LemmyErrorType};
use lemmy_utils::error::{LemmyErrorType, LemmyResult};
use serde::Deserialize;

#[derive(Deserialize, Clone)]
Expand Down
2 changes: 1 addition & 1 deletion crates/apub/src/http/person.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use activitypub_federation::{config::Data, traits::Object};
use actix_web::{web, HttpResponse};
use lemmy_api_common::{context::LemmyContext, utils::generate_outbox_url};
use lemmy_db_schema::{source::person::Person, traits::ApubActor};
use lemmy_utils::{error::LemmyResult, LemmyErrorType};
use lemmy_utils::error::{LemmyErrorType, LemmyResult};
use serde::Deserialize;

#[derive(Deserialize)]
Expand Down
14 changes: 8 additions & 6 deletions crates/apub/src/objects/comment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use crate::{
check_apub_id_valid_with_strictness,
fetcher::markdown_links::markdown_rewrite_remote_links,
mentions::collect_non_local_mentions,
objects::{read_from_string_or_source, verify_is_remote_object},
objects::{append_attachments_to_comment, read_from_string_or_source, verify_is_remote_object},
protocol::{
objects::{note::Note, LanguageTag},
InCommunity,
Expand Down Expand Up @@ -124,6 +124,7 @@ impl Object for ApubComment {
distinguished: Some(self.distinguished),
language,
audience: Some(community.actor_id.into()),
attachment: vec![],
};

Ok(note)
Expand Down Expand Up @@ -181,6 +182,7 @@ impl Object for ApubComment {
let local_site = LocalSite::read(&mut context.pool()).await.ok();
let slur_regex = &local_site_opt_to_slur_regex(&local_site);
let url_blocklist = get_url_blocklist(context).await?;
let content = append_attachments_to_comment(content, &note.attachment, context).await?;
let content = process_markdown(&content, slur_regex, &url_blocklist, context).await?;
let content = markdown_rewrite_remote_links(content, context).await;
let language_id = Some(
Expand Down Expand Up @@ -247,13 +249,13 @@ pub(crate) mod tests {
}

async fn cleanup(
data: (ApubPerson, ApubCommunity, ApubPost, ApubSite),
(person, community, post, site): (ApubPerson, ApubCommunity, ApubPost, ApubSite),
context: &LemmyContext,
) -> LemmyResult<()> {
Post::delete(&mut context.pool(), data.2.id).await?;
Community::delete(&mut context.pool(), data.1.id).await?;
Person::delete(&mut context.pool(), data.0.id).await?;
Site::delete(&mut context.pool(), data.3.id).await?;
Post::delete(&mut context.pool(), post.id).await?;
Community::delete(&mut context.pool(), community.id).await?;
Person::delete(&mut context.pool(), person.id).await?;
Site::delete(&mut context.pool(), site.id).await?;
LocalSite::delete(&mut context.pool()).await?;
Ok(())
}
Expand Down
19 changes: 18 additions & 1 deletion crates/apub/src/objects/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::protocol::Source;
use crate::protocol::{objects::page::Attachment, Source};
use activitypub_federation::{
config::Data,
fetch::object_id::ObjectId,
Expand Down Expand Up @@ -46,6 +46,23 @@ pub(crate) fn read_from_string_or_source_opt(
.map(|content| read_from_string_or_source(content, media_type, source))
}

pub(crate) async fn append_attachments_to_comment(
content: String,
attachments: &[Attachment],
context: &Data<LemmyContext>,
) -> LemmyResult<String> {
let mut content = content;
// Don't modify comments with no attachments
if !attachments.is_empty() {
content += "\n";
for attachment in attachments {
content = content + "\n" + &attachment.as_markdown(context).await?;
}
}

Ok(content)
}

/// When for example a Post is made in a remote community, the community will send it back,
/// wrapped in Announce. If we simply receive this like any other federated object, overwrite the
/// existing, local Post. In particular, it will set the field local = false, so that the object
Expand Down
9 changes: 6 additions & 3 deletions crates/apub/src/objects/person.rs
Original file line number Diff line number Diff line change
Expand Up @@ -285,9 +285,12 @@ pub(crate) mod tests {
Ok(())
}

async fn cleanup(data: (ApubPerson, ApubSite), context: &LemmyContext) -> LemmyResult<()> {
DbPerson::delete(&mut context.pool(), data.0.id).await?;
Site::delete(&mut context.pool(), data.1.id).await?;
async fn cleanup(
(person, site): (ApubPerson, ApubSite),
context: &LemmyContext,
) -> LemmyResult<()> {
DbPerson::delete(&mut context.pool(), person.id).await?;
Site::delete(&mut context.pool(), site.id).await?;
Ok(())
}
}
8 changes: 4 additions & 4 deletions crates/apub/src/objects/private_message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -186,12 +186,12 @@ mod tests {
}

async fn cleanup(
data: (ApubPerson, ApubPerson, ApubSite),
(person1, person2, site): (ApubPerson, ApubPerson, ApubSite),
context: &Data<LemmyContext>,
) -> LemmyResult<()> {
Person::delete(&mut context.pool(), data.0.id).await?;
Person::delete(&mut context.pool(), data.1.id).await?;
Site::delete(&mut context.pool(), data.2.id).await?;
Person::delete(&mut context.pool(), person1.id).await?;
Person::delete(&mut context.pool(), person2.id).await?;
Site::delete(&mut context.pool(), site.id).await?;
Ok(())
}

Expand Down
3 changes: 2 additions & 1 deletion crates/apub/src/protocol/objects/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,8 @@ mod tests {
#[test]
fn test_parse_objects_mastodon() -> LemmyResult<()> {
test_json::<Person>("assets/mastodon/objects/person.json")?;
test_json::<Note>("assets/mastodon/objects/note.json")?;
test_json::<Note>("assets/mastodon/objects/note_1.json")?;
test_json::<Note>("assets/mastodon/objects/note_2.json")?;
test_json::<Page>("assets/mastodon/objects/page.json")?;
Ok(())
}
Expand Down
13 changes: 11 additions & 2 deletions crates/apub/src/protocol/objects/note.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@ use crate::{
fetcher::post_or_comment::PostOrComment,
mentions::MentionOrValue,
objects::{comment::ApubComment, community::ApubCommunity, person::ApubPerson, post::ApubPost},
protocol::{objects::LanguageTag, InCommunity, Source},
protocol::{
objects::{page::Attachment, LanguageTag},
InCommunity,
Source,
},
};
use activitypub_federation::{
config::Data,
Expand All @@ -20,7 +24,10 @@ use lemmy_db_schema::{
source::{community::Community, post::Post},
traits::Crud,
};
use lemmy_utils::{error::LemmyResult, LemmyErrorType, MAX_COMMENT_DEPTH_LIMIT};
use lemmy_utils::{
error::{LemmyErrorType, LemmyResult},
MAX_COMMENT_DEPTH_LIMIT,
};
use serde::{Deserialize, Serialize};
use serde_with::skip_serializing_none;
use url::Url;
Expand Down Expand Up @@ -50,6 +57,8 @@ pub struct Note {
pub(crate) distinguished: Option<bool>,
pub(crate) language: Option<LanguageTag>,
pub(crate) audience: Option<ObjectId<ApubCommunity>>,
#[serde(default)]
pub(crate) attachment: Vec<Attachment>,
}

impl Note {
Expand Down
21 changes: 20 additions & 1 deletion crates/apub/src/protocol/objects/page.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use activitypub_federation::{
};
use chrono::{DateTime, Utc};
use itertools::Itertools;
use lemmy_api_common::context::LemmyContext;
use lemmy_api_common::{context::LemmyContext, utils::proxy_image_link};
use lemmy_utils::error::{FederationError, LemmyError, LemmyErrorType, LemmyResult};
use serde::{de::Error, Deserialize, Deserializer, Serialize};
use serde_with::skip_serializing_none;
Expand Down Expand Up @@ -93,6 +93,7 @@ pub(crate) struct Document {
#[serde(rename = "type")]
kind: DocumentType,
url: Url,
media_type: Option<String>,
/// Used for alt_text
name: Option<String>,
}
Expand Down Expand Up @@ -124,6 +125,24 @@ impl Attachment {
_ => None,
}
}

pub(crate) async fn as_markdown(&self, context: &Data<LemmyContext>) -> LemmyResult<String> {
let (url, name, media_type) = match self {
Attachment::Image(i) => (i.url.clone(), i.name.clone(), Some(String::from("image"))),
Attachment::Document(d) => (d.url.clone(), d.name.clone(), d.media_type.clone()),
Attachment::Link(l) => (l.href.clone(), None, l.media_type.clone()),
};

let is_image =
media_type.is_some_and(|media| media.starts_with("video") || media.starts_with("image"));

if is_image {
let url = proxy_image_link(url, context).await?;
Ok(format!("![{}]({url})", name.unwrap_or_default()))
} else {
Ok(format!("[{url}]({url})"))
}
}
}

#[derive(Clone, Debug, Deserialize, Serialize)]
Expand Down
Loading

0 comments on commit 104f71d

Please sign in to comment.