diff --git a/.woodpecker.yml b/.woodpecker.yml
index 6e30293de..1ae2df457 100644
--- a/.woodpecker.yml
+++ b/.woodpecker.yml
@@ -262,6 +262,19 @@ steps:
when:
event: cron
+ # using https://github.com/pksunkara/cargo-workspaces
+ publish_to_crates_io:
+ image: *rust_image
+ commands:
+ - 'echo "pub const VERSION: &str = \"$(git describe --tag)\";" > "crates/utils/src/version.rs"'
+ - cargo install cargo-workspaces
+ - cp -r migrations crates/db_schema/
+ - cargo login "$CARGO_API_TOKEN"
+ - cargo workspaces publish --from-git --allow-dirty --no-verify --allow-branch "${CI_COMMIT_TAG}" --yes custom "${CI_COMMIT_TAG}"
+ secrets: [cargo_api_token]
+ when:
+ event: tag
+
notify_on_failure:
image: alpine:3
commands:
diff --git a/Cargo.lock b/Cargo.lock
index 337c7628e..edbd43efd 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2523,7 +2523,7 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "lemmy_api"
-version = "0.19.0"
+version = "0.19.1-rc.2"
dependencies = [
"activitypub_federation",
"actix-web",
@@ -2551,7 +2551,7 @@ dependencies = [
[[package]]
name = "lemmy_api_common"
-version = "0.19.0"
+version = "0.19.1-rc.2"
dependencies = [
"activitypub_federation",
"actix-web",
@@ -2585,7 +2585,7 @@ dependencies = [
[[package]]
name = "lemmy_api_crud"
-version = "0.19.0"
+version = "0.19.1-rc.2"
dependencies = [
"activitypub_federation",
"actix-web",
@@ -2607,7 +2607,7 @@ dependencies = [
[[package]]
name = "lemmy_apub"
-version = "0.19.0"
+version = "0.19.1-rc.2"
dependencies = [
"activitypub_federation",
"actix-web",
@@ -2659,7 +2659,7 @@ dependencies = [
[[package]]
name = "lemmy_db_schema"
-version = "0.19.0"
+version = "0.19.1-rc.2"
dependencies = [
"activitypub_federation",
"anyhow",
@@ -2696,7 +2696,7 @@ dependencies = [
[[package]]
name = "lemmy_db_views"
-version = "0.19.0"
+version = "0.19.1-rc.2"
dependencies = [
"actix-web",
"chrono",
@@ -2715,7 +2715,7 @@ dependencies = [
[[package]]
name = "lemmy_db_views_actor"
-version = "0.19.0"
+version = "0.19.1-rc.2"
dependencies = [
"chrono",
"diesel",
@@ -2732,7 +2732,7 @@ dependencies = [
[[package]]
name = "lemmy_db_views_moderator"
-version = "0.19.0"
+version = "0.19.1-rc.2"
dependencies = [
"diesel",
"diesel-async",
@@ -2744,7 +2744,7 @@ dependencies = [
[[package]]
name = "lemmy_federate"
-version = "0.19.0"
+version = "0.19.1-rc.2"
dependencies = [
"activitypub_federation",
"anyhow",
@@ -2767,7 +2767,7 @@ dependencies = [
[[package]]
name = "lemmy_routes"
-version = "0.19.0"
+version = "0.19.1-rc.2"
dependencies = [
"activitypub_federation",
"actix-web",
@@ -2791,7 +2791,7 @@ dependencies = [
[[package]]
name = "lemmy_server"
-version = "0.19.0"
+version = "0.19.1-rc.2"
dependencies = [
"activitypub_federation",
"actix-cors",
@@ -2833,7 +2833,7 @@ dependencies = [
[[package]]
name = "lemmy_utils"
-version = "0.19.0"
+version = "0.19.1-rc.2"
dependencies = [
"actix-web",
"anyhow",
diff --git a/Cargo.toml b/Cargo.toml
index 6985db965..f17b756a8 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,5 +1,6 @@
[workspace.package]
-version = "0.19.0"
+version = "0.19.1-rc.2"
+publish = false
edition = "2021"
description = "A link aggregator for the fediverse"
license = "AGPL-3.0"
@@ -85,16 +86,16 @@ unused_self = "deny"
unwrap_used = "deny"
[workspace.dependencies]
-lemmy_api = { version = "=0.19.0", path = "./crates/api" }
-lemmy_api_crud = { version = "=0.19.0", path = "./crates/api_crud" }
-lemmy_apub = { version = "=0.19.0", path = "./crates/apub" }
-lemmy_utils = { version = "=0.19.0", path = "./crates/utils" }
-lemmy_db_schema = { version = "=0.19.0", path = "./crates/db_schema" }
-lemmy_api_common = { version = "=0.19.0", path = "./crates/api_common" }
-lemmy_routes = { version = "=0.19.0", path = "./crates/routes" }
-lemmy_db_views = { version = "=0.19.0", path = "./crates/db_views" }
-lemmy_db_views_actor = { version = "=0.19.0", path = "./crates/db_views_actor" }
-lemmy_db_views_moderator = { version = "=0.19.0", path = "./crates/db_views_moderator" }
+lemmy_api = { version = "=0.19.1-rc.2", path = "./crates/api" }
+lemmy_api_crud = { version = "=0.19.1-rc.2", path = "./crates/api_crud" }
+lemmy_apub = { version = "=0.19.1-rc.2", path = "./crates/apub" }
+lemmy_utils = { version = "=0.19.1-rc.2", path = "./crates/utils" }
+lemmy_db_schema = { version = "=0.19.1-rc.2", path = "./crates/db_schema" }
+lemmy_api_common = { version = "=0.19.1-rc.2", path = "./crates/api_common" }
+lemmy_routes = { version = "=0.19.1-rc.2", path = "./crates/routes" }
+lemmy_db_views = { version = "=0.19.1-rc.2", path = "./crates/db_views" }
+lemmy_db_views_actor = { version = "=0.19.1-rc.2", path = "./crates/db_views_actor" }
+lemmy_db_views_moderator = { version = "=0.19.1-rc.2", path = "./crates/db_views_moderator" }
activitypub_federation = { version = "0.5.0-beta.6", default-features = false, features = [
"actix-web",
] }
@@ -166,7 +167,7 @@ lemmy_utils = { workspace = true }
lemmy_db_schema = { workspace = true }
lemmy_api_common = { workspace = true }
lemmy_routes = { workspace = true }
-lemmy_federate = { version = "0.19.0", path = "crates/federate" }
+lemmy_federate = { version = "0.19.1-rc.2", path = "crates/federate" }
activitypub_federation = { workspace = true }
diesel = { workspace = true }
diesel-async = { workspace = true }
diff --git a/README.md b/README.md
index a3f6ceb2a..3227f74d8 100644
--- a/README.md
+++ b/README.md
@@ -7,7 +7,7 @@
[![Translation status](http://weblate.join-lemmy.org/widgets/lemmy/-/lemmy/svg-badge.svg)](http://weblate.join-lemmy.org/engage/lemmy/)
[![License](https://img.shields.io/github/license/LemmyNet/lemmy.svg)](LICENSE)
![GitHub stars](https://img.shields.io/github/stars/LemmyNet/lemmy?style=social)
-[![Delightful Humane Tech](https://codeberg.org/teaserbot-labs/delightful-humane-design/raw/branch/main/humane-tech-badge.svg)](https://codeberg.org/teaserbot-labs/delightful-humane-design)
+
diff --git a/api_tests/prepare-drone-federation-test.sh b/api_tests/prepare-drone-federation-test.sh
index 0f7591b31..4710168d9 100755
--- a/api_tests/prepare-drone-federation-test.sh
+++ b/api_tests/prepare-drone-federation-test.sh
@@ -9,7 +9,7 @@ export RUST_LOG="warn,lemmy_server=debug,lemmy_federate=debug,lemmy_api=debug,le
export LEMMY_TEST_FAST_FEDERATION=1 # by default, the persistent federation queue has delays in the scale of 30s-5min
# pictrs setup
-if ! [ -f "pict-rs" ]; then
+if [ ! -f "pict-rs" ]; then
curl "https://git.asonix.dog/asonix/pict-rs/releases/download/v0.5.0-beta.2/pict-rs-linux-amd64" -o api_tests/pict-rs
chmod +x api_tests/pict-rs
fi
diff --git a/api_tests/src/private_message.spec.ts b/api_tests/src/private_message.spec.ts
index 08c519df7..75dcaee33 100644
--- a/api_tests/src/private_message.spec.ts
+++ b/api_tests/src/private_message.spec.ts
@@ -10,6 +10,7 @@ import {
deletePrivateMessage,
unfollowRemotes,
waitUntil,
+ reportPrivateMessage,
} from "./shared";
let recipient_id: number;
@@ -109,3 +110,42 @@ test("Delete a private message", async () => {
betaPms1.private_messages.length,
);
});
+
+test("Create a private message report", async () => {
+ let pmRes = await createPrivateMessage(alpha, recipient_id);
+ let betaPms1 = await waitUntil(
+ () => listPrivateMessages(beta),
+ m =>
+ !!m.private_messages.find(
+ e =>
+ e.private_message.ap_id ===
+ pmRes.private_message_view.private_message.ap_id,
+ ),
+ );
+ let betaPm = betaPms1.private_messages[0];
+ expect(betaPm).toBeDefined();
+
+ // Make sure that only the recipient can report it, so this should fail
+ await expect(
+ reportPrivateMessage(
+ alpha,
+ pmRes.private_message_view.private_message.id,
+ "a reason",
+ ),
+ ).rejects.toStrictEqual(Error("couldnt_create_report"));
+
+ // This one should pass
+ let reason = "another reason";
+ let report = await reportPrivateMessage(
+ beta,
+ betaPm.private_message.id,
+ reason,
+ );
+
+ expect(report.private_message_report_view.private_message.id).toBe(
+ betaPm.private_message.id,
+ );
+ expect(report.private_message_report_view.private_message_report.reason).toBe(
+ reason,
+ );
+});
diff --git a/api_tests/src/shared.ts b/api_tests/src/shared.ts
index 0545eee57..fe51fb046 100644
--- a/api_tests/src/shared.ts
+++ b/api_tests/src/shared.ts
@@ -4,12 +4,14 @@ import {
BlockInstance,
BlockInstanceResponse,
CommunityId,
+ CreatePrivateMessageReport,
GetReplies,
GetRepliesResponse,
GetUnreadCountResponse,
InstanceId,
LemmyHttp,
PostView,
+ PrivateMessageReportResponse,
SuccessResponse,
} from "lemmy-js-client";
import { CreatePost } from "lemmy-js-client/dist/types/CreatePost";
@@ -781,6 +783,18 @@ export async function reportComment(
return api.createCommentReport(form);
}
+export async function reportPrivateMessage(
+ api: LemmyHttp,
+ private_message_id: number,
+ reason: string,
+): Promise {
+ let form: CreatePrivateMessageReport = {
+ private_message_id,
+ reason,
+ };
+ return api.createPrivateMessageReport(form);
+}
+
export async function listCommentReports(
api: LemmyHttp,
): Promise {
diff --git a/crates/api/Cargo.toml b/crates/api/Cargo.toml
index 6327e45fd..f22c9192a 100644
--- a/crates/api/Cargo.toml
+++ b/crates/api/Cargo.toml
@@ -1,5 +1,6 @@
[package]
name = "lemmy_api"
+publish = false
version.workspace = true
edition.workspace = true
description.workspace = true
diff --git a/crates/api/src/private_message_report/create.rs b/crates/api/src/private_message_report/create.rs
index 75620bf8b..7aca9661b 100644
--- a/crates/api/src/private_message_report/create.rs
+++ b/crates/api/src/private_message_report/create.rs
@@ -31,6 +31,11 @@ pub async fn create_pm_report(
let private_message_id = data.private_message_id;
let private_message = PrivateMessage::read(&mut context.pool(), private_message_id).await?;
+ // Make sure that only the recipient of the private message can create a report
+ if person_id != private_message.recipient_id {
+ Err(LemmyErrorType::CouldntCreateReport)?
+ }
+
let report_form = PrivateMessageReportForm {
creator_id: person_id,
private_message_id,
diff --git a/crates/api_common/src/send_activity.rs b/crates/api_common/src/send_activity.rs
index 6d9c722a1..ceaed4826 100644
--- a/crates/api_common/src/send_activity.rs
+++ b/crates/api_common/src/send_activity.rs
@@ -98,9 +98,9 @@ impl ActivityChannel {
Ok(())
}
- pub async fn close(outgoing_activities_task: JoinHandle>) -> LemmyResult<()> {
+ pub async fn close(outgoing_activities_task: JoinHandle<()>) -> LemmyResult<()> {
ACTIVITY_CHANNEL.keepalive_sender.lock().await.take();
- outgoing_activities_task.await??;
+ outgoing_activities_task.await?;
Ok(())
}
}
diff --git a/crates/api_crud/Cargo.toml b/crates/api_crud/Cargo.toml
index ea7c81399..f4f89c2e5 100644
--- a/crates/api_crud/Cargo.toml
+++ b/crates/api_crud/Cargo.toml
@@ -1,5 +1,6 @@
[package]
name = "lemmy_api_crud"
+publish = false
version.workspace = true
edition.workspace = true
description.workspace = true
diff --git a/crates/apub/Cargo.toml b/crates/apub/Cargo.toml
index d0e226aa4..82f9812e6 100644
--- a/crates/apub/Cargo.toml
+++ b/crates/apub/Cargo.toml
@@ -1,5 +1,6 @@
[package]
name = "lemmy_apub"
+publish = false
version.workspace = true
edition.workspace = true
description.workspace = true
diff --git a/crates/apub/src/activities/mod.rs b/crates/apub/src/activities/mod.rs
index ee3eb16ff..83d029d4e 100644
--- a/crates/apub/src/activities/mod.rs
+++ b/crates/apub/src/activities/mod.rs
@@ -225,11 +225,12 @@ where
Ok(())
}
-pub async fn handle_outgoing_activities(context: Data) -> LemmyResult<()> {
+pub async fn handle_outgoing_activities(context: Data) {
while let Some(data) = ActivityChannel::retrieve_activity().await {
- match_outgoing_activities(data, &context.reset_request_count()).await?
+ if let Err(e) = match_outgoing_activities(data, &context.reset_request_count()).await {
+ tracing::warn!("error while saving outgoing activity to db: {e}");
+ }
}
- Ok(())
}
pub async fn match_outgoing_activities(
diff --git a/crates/db_schema/src/impls/comment.rs b/crates/db_schema/src/impls/comment.rs
index aef399c59..7173b79d2 100644
--- a/crates/db_schema/src/impls/comment.rs
+++ b/crates/db_schema/src/impls/comment.rs
@@ -87,7 +87,7 @@ impl Comment {
let updated_comment = diesel::update(comment.find(comment_id))
.set(path.eq(ltree))
.get_result::(conn)
- .await;
+ .await?;
// Update the child count for the parent comment_aggregates
// You could do this with a trigger, but since you have to do this manually anyway,
@@ -121,7 +121,7 @@ where ca.comment_id = c.id"
sql_query(update_child_count_stmt).execute(conn).await?;
}
}
- updated_comment
+ Ok(updated_comment)
}) as _
})
.await
diff --git a/crates/db_views/src/post_view.rs b/crates/db_views/src/post_view.rs
index edeb4ba44..7d42c7c22 100644
--- a/crates/db_views/src/post_view.rs
+++ b/crates/db_views/src/post_view.rs
@@ -416,7 +416,8 @@ fn queries<'a>() -> Queries<
.unwrap_or(true)
{
// Do not hide read posts when it is a user profile view
- if let (Some(_creator_id), Some(person_id)) = (options.creator_id, my_person_id) {
+ // Or, only hide read posts on non-profile views
+ if let (None, Some(person_id)) = (options.creator_id, my_person_id) {
query = query.filter(not(is_read(person_id)));
}
}
@@ -752,7 +753,7 @@ mod tests {
local_user::{LocalUser, LocalUserInsertForm, LocalUserUpdateForm},
person::{Person, PersonInsertForm},
person_block::{PersonBlock, PersonBlockForm},
- post::{Post, PostInsertForm, PostLike, PostLikeForm, PostUpdateForm},
+ post::{Post, PostInsertForm, PostLike, PostLikeForm, PostRead, PostUpdateForm},
},
traits::{Blockable, Crud, Joinable, Likeable},
utils::{build_db_pool_for_tests, DbPool, RANK_DEFAULT},
@@ -760,7 +761,7 @@ mod tests {
SubscribedType,
};
use serial_test::serial;
- use std::time::Duration;
+ use std::{collections::HashSet, time::Duration};
struct Data {
inserted_instance: Instance,
@@ -1508,6 +1509,47 @@ mod tests {
cleanup(data, pool).await;
}
+ #[tokio::test]
+ #[serial]
+ async fn post_listings_hide_read() {
+ let pool = &build_db_pool_for_tests().await;
+ let pool = &mut pool.into();
+ let mut data = init_data(pool).await;
+
+ // Make sure local user hides read posts
+ let local_user_form = LocalUserUpdateForm {
+ show_read_posts: Some(false),
+ ..Default::default()
+ };
+ let inserted_local_user =
+ LocalUser::update(pool, data.local_user_view.local_user.id, &local_user_form)
+ .await
+ .unwrap();
+ data.local_user_view.local_user = inserted_local_user;
+
+ // Mark a post as read
+ PostRead::mark_as_read(
+ pool,
+ HashSet::from([data.inserted_bot_post.id]),
+ data.local_user_view.person.id,
+ )
+ .await
+ .unwrap();
+
+ // Make sure you don't see the read post in the results
+ let post_listings_hide_read = PostQuery {
+ sort: Some(SortType::New),
+ local_user: Some(&data.local_user_view),
+ ..Default::default()
+ }
+ .list(pool)
+ .await
+ .unwrap();
+ assert_eq!(1, post_listings_hide_read.len());
+
+ cleanup(data, pool).await;
+ }
+
async fn cleanup(data: Data, pool: &mut DbPool<'_>) {
let num_deleted = Post::delete(pool, data.inserted_post.id).await.unwrap();
Community::delete(pool, data.inserted_community.id)
diff --git a/crates/db_views/src/private_message_view.rs b/crates/db_views/src/private_message_view.rs
index 54bae9482..26d97038c 100644
--- a/crates/db_views/src/private_message_view.rs
+++ b/crates/db_views/src/private_message_view.rs
@@ -210,7 +210,7 @@ mod tests {
.recipient_id(timmy.id)
.content(message_content.clone())
.build();
- let _inserted_sara_timmy_message_form = PrivateMessage::create(pool, &sara_timmy_message_form)
+ PrivateMessage::create(pool, &sara_timmy_message_form)
.await
.unwrap();
@@ -219,7 +219,7 @@ mod tests {
.recipient_id(jess.id)
.content(message_content.clone())
.build();
- let _inserted_sara_jess_message_form = PrivateMessage::create(pool, &sara_jess_message_form)
+ PrivateMessage::create(pool, &sara_jess_message_form)
.await
.unwrap();
@@ -228,7 +228,7 @@ mod tests {
.recipient_id(sara.id)
.content(message_content.clone())
.build();
- let _inserted_timmy_sara_message_form = PrivateMessage::create(pool, &timmy_sara_message_form)
+ PrivateMessage::create(pool, &timmy_sara_message_form)
.await
.unwrap();
@@ -237,13 +237,13 @@ mod tests {
.recipient_id(timmy.id)
.content(message_content.clone())
.build();
- let _inserted_jess_timmy_message_form = PrivateMessage::create(pool, &jess_timmy_message_form)
+ PrivateMessage::create(pool, &jess_timmy_message_form)
.await
.unwrap();
let timmy_messages = PrivateMessageQuery {
unread_only: false,
- creator_id: Option::None,
+ creator_id: None,
..Default::default()
}
.list(pool, timmy.id)
@@ -260,7 +260,7 @@ mod tests {
let timmy_unread_messages = PrivateMessageQuery {
unread_only: true,
- creator_id: Option::None,
+ creator_id: None,
..Default::default()
}
.list(pool, timmy.id)
@@ -320,7 +320,7 @@ mod tests {
let timmy_messages = PrivateMessageQuery {
unread_only: true,
- creator_id: Option::None,
+ creator_id: None,
..Default::default()
}
.list(pool, timmy.id)
@@ -333,5 +333,8 @@ mod tests {
.await
.unwrap();
assert_eq!(timmy_unread_messages, 1);
+
+ // This also deletes all persons and private messages thanks to sql `on delete cascade`
+ Instance::delete(pool, instance.id).await.unwrap();
}
}
diff --git a/crates/db_views_actor/src/person_view.rs b/crates/db_views_actor/src/person_view.rs
index f42fa15cf..16e9b3bc6 100644
--- a/crates/db_views_actor/src/person_view.rs
+++ b/crates/db_views_actor/src/person_view.rs
@@ -230,7 +230,6 @@ mod tests {
#[tokio::test]
#[serial]
- #[allow(clippy::dbg_macro)]
async fn exclude_deleted() {
let pool = &build_db_pool_for_tests().await;
let pool = &mut pool.into();
@@ -257,7 +256,6 @@ mod tests {
.list(pool)
.await
.unwrap();
- dbg!(&list);
assert_eq!(list.len(), 1);
assert_eq!(list[0].person.id, data.bob.id);
diff --git a/crates/federate/Cargo.toml b/crates/federate/Cargo.toml
index 38a0e1433..9ccd8adc3 100644
--- a/crates/federate/Cargo.toml
+++ b/crates/federate/Cargo.toml
@@ -1,5 +1,6 @@
[package]
name = "lemmy_federate"
+publish = false
version.workspace = true
edition.workspace = true
description.workspace = true
diff --git a/crates/federate/src/worker.rs b/crates/federate/src/worker.rs
index a383d61b2..963814ad9 100644
--- a/crates/federate/src/worker.rs
+++ b/crates/federate/src/worker.rs
@@ -171,6 +171,7 @@ impl InstanceWorker {
.await
.context("failed reading activity from db")?
else {
+ tracing::debug!("{}: {:?} does not exist", self.instance.domain, id);
self.state.last_successful_id = Some(id);
continue;
};
diff --git a/crates/routes/Cargo.toml b/crates/routes/Cargo.toml
index 40fa2ab01..82c786576 100644
--- a/crates/routes/Cargo.toml
+++ b/crates/routes/Cargo.toml
@@ -1,5 +1,6 @@
[package]
name = "lemmy_routes"
+publish = false
version.workspace = true
edition.workspace = true
description.workspace = true
diff --git a/crates/utils/translations b/crates/utils/translations
index 7a38baa73..15815aea7 160000
--- a/crates/utils/translations
+++ b/crates/utils/translations
@@ -1 +1 @@
-Subproject commit 7a38baa7341cfa9299df5a80ebe42fe298380e40
+Subproject commit 15815aea74fe97360afc03496b3ad62588649af0
diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml
index 4c1a67411..eb81766cc 100644
--- a/docker/docker-compose.yml
+++ b/docker/docker-compose.yml
@@ -77,7 +77,7 @@ services:
init: true
pictrs:
- image: asonix/pictrs:0.4.0-beta.19
+ image: asonix/pictrs:0.5.0-rc.2
# this needs to match the pictrs url in lemmy.hjson
hostname: pictrs
# we can set options to pictrs like this, here we set max. image size and forced format for conversion
diff --git a/docker/federation/docker-compose.yml b/docker/federation/docker-compose.yml
index 6e0e7f2d2..a8c6160df 100644
--- a/docker/federation/docker-compose.yml
+++ b/docker/federation/docker-compose.yml
@@ -49,7 +49,7 @@ services:
pictrs:
restart: always
- image: asonix/pictrs:0.4.0-beta.19
+ image: asonix/pictrs:0.5.0-rc.2
user: 991:991
volumes:
- ./volumes/pictrs_alpha:/mnt:Z