From c1db65c6e55cf179926f8ec1689aec94faa89da9 Mon Sep 17 00:00:00 2001 From: Dessalines Date: Thu, 19 Oct 2023 20:15:55 -0400 Subject: [PATCH 1/6] Fix up convert more responses to SuccessResponse (#4066) * Revert "Convert more responses to SuccessResponse. Fixes #2860 (#4058)" This reverts commit 8deb4e5752cb9482d8082df559d81b9e1c573a94. * Removing purgeitem and deletecustomemoji response. * Adding back in utils building. --- api_tests/package.json | 2 +- api_tests/src/community.spec.ts | 3 +- api_tests/src/post.spec.ts | 8 ++--- api_tests/src/shared.ts | 15 +++++--- api_tests/yarn.lock | 8 ++--- crates/api/src/community/add_mod.rs | 13 ++++--- crates/api/src/community/ban.rs | 10 +++--- crates/api/src/community/block.rs | 10 +++--- crates/api/src/local_user/add_admin.rs | 13 +++++-- crates/api/src/local_user/ban_person.rs | 10 +++--- crates/api/src/local_user/block.rs | 14 ++++++-- .../notifications/mark_reply_read.rs | 15 ++++++-- crates/api/src/site/block.rs | 11 ++++-- crates/api_common/src/community.rs | 29 +++++++++++++++- crates/api_common/src/person.rs | 34 +++++++++++++++++++ crates/api_common/src/site.rs | 8 +++++ 16 files changed, 159 insertions(+), 44 deletions(-) diff --git a/api_tests/package.json b/api_tests/package.json index 892484709..84e5d3df5 100644 --- a/api_tests/package.json +++ b/api_tests/package.json @@ -19,7 +19,7 @@ "eslint": "^8.51.0", "eslint-plugin-prettier": "^5.0.1", "jest": "^29.5.0", - "lemmy-js-client": "0.19.0-alpha.12", + "lemmy-js-client": "0.19.0-rc.12", "prettier": "^3.0.0", "ts-jest": "^29.1.0", "typescript": "^5.0.4" diff --git a/api_tests/src/community.spec.ts b/api_tests/src/community.spec.ts index a67cd693a..2c97d629f 100644 --- a/api_tests/src/community.spec.ts +++ b/api_tests/src/community.spec.ts @@ -25,6 +25,7 @@ import { getCommunityByName, blockInstance, waitUntil, + delay, alphaUrl, delta, betaAllowedInstances, @@ -240,7 +241,7 @@ test("Admin actions in remote community are not federated to origin", async () = true, true, ); - expect(banRes.success).toBe(true); + expect(banRes.banned).toBe(true); // ban doesnt federate to community's origin instance alpha let alphaPost = (await resolvePost(alpha, gammaPost.post)).post; diff --git a/api_tests/src/post.spec.ts b/api_tests/src/post.spec.ts index f9af236ce..8c1f22226 100644 --- a/api_tests/src/post.spec.ts +++ b/api_tests/src/post.spec.ts @@ -415,7 +415,7 @@ test("Enforce site ban for federated user", async () => { true, true, ); - expect(banAlpha.success).toBe(true); + expect(banAlpha.banned).toBe(true); // alpha ban should be federated to beta let alphaUserOnBeta1 = await waitUntil( @@ -437,7 +437,7 @@ test("Enforce site ban for federated user", async () => { false, false, ); - expect(unBanAlpha.success).toBe(true); + expect(unBanAlpha.banned).toBe(false); // Login gets invalidated by ban, need to login again if (!alphaUserPerson) { @@ -479,7 +479,7 @@ test.skip("Enforce community ban for federated user", async () => { true, true, ); - expect(banAlpha.success).toBe(true); + expect(banAlpha.banned).toBe(true); // ensure that the post by alpha got removed await expect(getPost(alpha, searchBeta1.posts[0].post.id)).rejects.toBe( @@ -499,7 +499,7 @@ test.skip("Enforce community ban for federated user", async () => { false, false, ); - expect(unBanAlpha.success).toBe(true); + expect(unBanAlpha.banned).toBe(false); let postRes3 = await createPost(alpha, betaCommunity.community.id); expect(postRes3.post_view.post).toBeDefined(); expect(postRes3.post_view.community.local).toBe(false); diff --git a/api_tests/src/shared.ts b/api_tests/src/shared.ts index fce25adc2..e4dabb1d4 100644 --- a/api_tests/src/shared.ts +++ b/api_tests/src/shared.ts @@ -1,12 +1,12 @@ import { BlockInstance, + BlockInstanceResponse, GetReplies, GetRepliesResponse, GetUnreadCountResponse, InstanceId, LemmyHttp, PostView, - SuccessResponse, } from "lemmy-js-client"; import { CreatePost } from "lemmy-js-client/dist/types/CreatePost"; import { DeletePost } from "lemmy-js-client/dist/types/DeletePost"; @@ -27,7 +27,9 @@ import { ResolveObjectResponse } from "lemmy-js-client/dist/types/ResolveObjectR import { Search } from "lemmy-js-client/dist/types/Search"; import { SearchResponse } from "lemmy-js-client/dist/types/SearchResponse"; import { Comment } from "lemmy-js-client/dist/types/Comment"; +import { BanPersonResponse } from "lemmy-js-client/dist/types/BanPersonResponse"; import { BanPerson } from "lemmy-js-client/dist/types/BanPerson"; +import { BanFromCommunityResponse } from "lemmy-js-client/dist/types/BanFromCommunityResponse"; import { BanFromCommunity } from "lemmy-js-client/dist/types/BanFromCommunity"; import { CommunityResponse } from "lemmy-js-client/dist/types/CommunityResponse"; import { FollowCommunity } from "lemmy-js-client/dist/types/FollowCommunity"; @@ -53,6 +55,7 @@ import { Register } from "lemmy-js-client/dist/types/Register"; import { SaveUserSettings } from "lemmy-js-client/dist/types/SaveUserSettings"; import { DeleteAccount } from "lemmy-js-client/dist/types/DeleteAccount"; import { GetSiteResponse } from "lemmy-js-client/dist/types/GetSiteResponse"; +import { DeleteAccountResponse } from "lemmy-js-client/dist/types/DeleteAccountResponse"; import { PrivateMessagesResponse } from "lemmy-js-client/dist/types/PrivateMessagesResponse"; import { GetPrivateMessages } from "lemmy-js-client/dist/types/GetPrivateMessages"; import { PostReportResponse } from "lemmy-js-client/dist/types/PostReportResponse"; @@ -382,7 +385,7 @@ export async function banPersonFromSite( person_id: number, ban: boolean, remove_data: boolean, -): Promise { +): Promise { // Make sure lemmy-beta/c/main is cached on lemmy_alpha let form: BanPerson = { person_id, @@ -398,7 +401,7 @@ export async function banPersonFromCommunity( community_id: number, remove_data: boolean, ban: boolean, -): Promise { +): Promise { let form: BanFromCommunity = { person_id, community_id, @@ -686,7 +689,9 @@ export async function getPersonDetails( return api.getPersonDetails(form); } -export async function deleteUser(api: LemmyHttp): Promise { +export async function deleteUser( + api: LemmyHttp, +): Promise { let form: DeleteAccount = { delete_content: true, password, @@ -783,7 +788,7 @@ export function blockInstance( api: LemmyHttp, instance_id: InstanceId, block: boolean, -): Promise { +): Promise { let form: BlockInstance = { instance_id, block, diff --git a/api_tests/yarn.lock b/api_tests/yarn.lock index f528a9144..56764e096 100644 --- a/api_tests/yarn.lock +++ b/api_tests/yarn.lock @@ -2275,10 +2275,10 @@ kleur@^3.0.3: resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e" integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w== -lemmy-js-client@0.19.0-alpha.12: - version "0.19.0-alpha.12" - resolved "https://registry.yarnpkg.com/lemmy-js-client/-/lemmy-js-client-0.19.0-alpha.12.tgz#0f98743483b3859414e7accce905105a7fc6df78" - integrity sha512-4SicZRNxZpLAxrjP54eRJmFHJ2AjNbWJv3PuTp2g6tkLQPUukDr8RsEOoDXDoIoqadgR3B5z1ujnuTtQrVrFKg== +lemmy-js-client@0.19.0-rc.12: + version "0.19.0-rc.12" + resolved "https://registry.yarnpkg.com/lemmy-js-client/-/lemmy-js-client-0.19.0-rc.12.tgz#e3bd4e21b1966d583ab790ef70ece8394b012b48" + integrity sha512-1iu2fW9vlb3TrI+QR/ODP3+5pWZB0rUqL1wH09IzomDXohCqoQvfmXpwArmgF4Eq8GZgjkcfeMDC2gMrfw/i7Q== dependencies: cross-fetch "^3.1.5" form-data "^4.0.0" diff --git a/crates/api/src/community/add_mod.rs b/crates/api/src/community/add_mod.rs index e8bf2c19f..9d055c654 100644 --- a/crates/api/src/community/add_mod.rs +++ b/crates/api/src/community/add_mod.rs @@ -1,11 +1,10 @@ use activitypub_federation::config::Data; use actix_web::web::Json; use lemmy_api_common::{ - community::AddModToCommunity, + community::{AddModToCommunity, AddModToCommunityResponse}, context::LemmyContext, send_activity::{ActivityChannel, SendActivityData}, utils::check_community_mod_action, - SuccessResponse, }; use lemmy_db_schema::{ source::{ @@ -15,6 +14,7 @@ use lemmy_db_schema::{ traits::{Crud, Joinable}, }; use lemmy_db_views::structs::LocalUserView; +use lemmy_db_views_actor::structs::CommunityModeratorView; use lemmy_utils::error::{LemmyError, LemmyErrorExt, LemmyErrorType}; #[tracing::instrument(skip(context))] @@ -22,7 +22,7 @@ pub async fn add_mod_to_community( data: Json, context: Data, local_user_view: LocalUserView, -) -> Result, LemmyError> { +) -> Result, LemmyError> { let community_id = data.community_id; // Verify that only mods or admins can add mod @@ -63,6 +63,11 @@ pub async fn add_mod_to_community( ModAddCommunity::create(&mut context.pool(), &form).await?; + // Note: in case a remote mod is added, this returns the old moderators list, it will only get + // updated once we receive an activity from the community (like `Announce/Add/Moderator`) + let community_id = data.community_id; + let moderators = CommunityModeratorView::for_community(&mut context.pool(), community_id).await?; + ActivityChannel::submit_activity( SendActivityData::AddModToCommunity( local_user_view.person, @@ -74,5 +79,5 @@ pub async fn add_mod_to_community( ) .await?; - Ok(Json(SuccessResponse::default())) + Ok(Json(AddModToCommunityResponse { moderators })) } diff --git a/crates/api/src/community/ban.rs b/crates/api/src/community/ban.rs index 8e315568d..f662c4a08 100644 --- a/crates/api/src/community/ban.rs +++ b/crates/api/src/community/ban.rs @@ -1,11 +1,10 @@ use activitypub_federation::config::Data; use actix_web::web::Json; use lemmy_api_common::{ - community::BanFromCommunity, + community::{BanFromCommunity, BanFromCommunityResponse}, context::LemmyContext, send_activity::{ActivityChannel, SendActivityData}, utils::{check_community_mod_action, check_expire_time, remove_user_data_in_community}, - SuccessResponse, }; use lemmy_db_schema::{ source::{ @@ -31,7 +30,7 @@ pub async fn ban_from_community( data: Json, context: Data, local_user_view: LocalUserView, -) -> Result, LemmyError> { +) -> Result, LemmyError> { let banned_person_id = data.person_id; let remove_data = data.remove_data.unwrap_or(false); let expires = check_expire_time(data.expires)?; @@ -103,5 +102,8 @@ pub async fn ban_from_community( ) .await?; - Ok(Json(SuccessResponse::default())) + Ok(Json(BanFromCommunityResponse { + person_view, + banned: data.ban, + })) } diff --git a/crates/api/src/community/block.rs b/crates/api/src/community/block.rs index 3c4e7ed9c..fd4a5a01b 100644 --- a/crates/api/src/community/block.rs +++ b/crates/api/src/community/block.rs @@ -1,10 +1,9 @@ use activitypub_federation::config::Data; use actix_web::web::Json; use lemmy_api_common::{ - community::BlockCommunity, + community::{BlockCommunity, BlockCommunityResponse}, context::LemmyContext, send_activity::{ActivityChannel, SendActivityData}, - SuccessResponse, }; use lemmy_db_schema::{ source::{ @@ -22,7 +21,7 @@ pub async fn block_community( data: Json, context: Data, local_user_view: LocalUserView, -) -> Result, LemmyError> { +) -> Result, LemmyError> { let community_id = data.community_id; let person_id = local_user_view.person.id; let community_block_form = CommunityBlockForm { @@ -64,5 +63,8 @@ pub async fn block_community( ) .await?; - Ok(Json(SuccessResponse::default())) + Ok(Json(BlockCommunityResponse { + blocked: data.block, + community_view, + })) } diff --git a/crates/api/src/local_user/add_admin.rs b/crates/api/src/local_user/add_admin.rs index 0fc9989b9..502335876 100644 --- a/crates/api/src/local_user/add_admin.rs +++ b/crates/api/src/local_user/add_admin.rs @@ -1,5 +1,9 @@ use actix_web::web::{Data, Json}; -use lemmy_api_common::{context::LemmyContext, person::AddAdmin, utils::is_admin, SuccessResponse}; +use lemmy_api_common::{ + context::LemmyContext, + person::{AddAdmin, AddAdminResponse}, + utils::is_admin, +}; use lemmy_db_schema::{ source::{ local_user::{LocalUser, LocalUserUpdateForm}, @@ -8,6 +12,7 @@ use lemmy_db_schema::{ traits::Crud, }; use lemmy_db_views::structs::LocalUserView; +use lemmy_db_views_actor::structs::PersonView; use lemmy_utils::error::{LemmyError, LemmyErrorExt, LemmyErrorType}; #[tracing::instrument(skip(context))] @@ -15,7 +20,7 @@ pub async fn add_admin( data: Json, context: Data, local_user_view: LocalUserView, -) -> Result, LemmyError> { +) -> Result, LemmyError> { // Make sure user is an admin is_admin(&local_user_view)?; @@ -44,5 +49,7 @@ pub async fn add_admin( ModAdd::create(&mut context.pool(), &form).await?; - Ok(Json(SuccessResponse::default())) + let admins = PersonView::admins(&mut context.pool()).await?; + + Ok(Json(AddAdminResponse { admins })) } diff --git a/crates/api/src/local_user/ban_person.rs b/crates/api/src/local_user/ban_person.rs index caa30465d..d7c47e619 100644 --- a/crates/api/src/local_user/ban_person.rs +++ b/crates/api/src/local_user/ban_person.rs @@ -2,10 +2,9 @@ use activitypub_federation::config::Data; use actix_web::web::Json; use lemmy_api_common::{ context::LemmyContext, - person::BanPerson, + person::{BanPerson, BanPersonResponse}, send_activity::{ActivityChannel, SendActivityData}, utils::{check_expire_time, is_admin, remove_user_data}, - SuccessResponse, }; use lemmy_db_schema::{ source::{ @@ -27,7 +26,7 @@ pub async fn ban_from_site( data: Json, context: Data, local_user_view: LocalUserView, -) -> Result, LemmyError> { +) -> Result, LemmyError> { // Make sure user is an admin is_admin(&local_user_view)?; @@ -82,5 +81,8 @@ pub async fn ban_from_site( ) .await?; - Ok(Json(SuccessResponse::default())) + Ok(Json(BanPersonResponse { + person_view, + banned: data.ban, + })) } diff --git a/crates/api/src/local_user/block.rs b/crates/api/src/local_user/block.rs index 2524c0d8e..cb345616b 100644 --- a/crates/api/src/local_user/block.rs +++ b/crates/api/src/local_user/block.rs @@ -1,10 +1,14 @@ use actix_web::web::{Data, Json}; -use lemmy_api_common::{context::LemmyContext, person::BlockPerson, SuccessResponse}; +use lemmy_api_common::{ + context::LemmyContext, + person::{BlockPerson, BlockPersonResponse}, +}; use lemmy_db_schema::{ source::person_block::{PersonBlock, PersonBlockForm}, traits::Blockable, }; use lemmy_db_views::structs::LocalUserView; +use lemmy_db_views_actor::structs::PersonView; use lemmy_utils::error::{LemmyError, LemmyErrorExt, LemmyErrorType}; #[tracing::instrument(skip(context))] @@ -12,7 +16,7 @@ pub async fn block_person( data: Json, context: Data, local_user_view: LocalUserView, -) -> Result, LemmyError> { +) -> Result, LemmyError> { let target_id = data.person_id; let person_id = local_user_view.person.id; @@ -41,5 +45,9 @@ pub async fn block_person( .with_lemmy_type(LemmyErrorType::PersonBlockAlreadyExists)?; } - Ok(Json(SuccessResponse::default())) + let person_view = PersonView::read(&mut context.pool(), target_id).await?; + Ok(Json(BlockPersonResponse { + person_view, + blocked: data.block, + })) } diff --git a/crates/api/src/local_user/notifications/mark_reply_read.rs b/crates/api/src/local_user/notifications/mark_reply_read.rs index cc8a9774e..f7b259c94 100644 --- a/crates/api/src/local_user/notifications/mark_reply_read.rs +++ b/crates/api/src/local_user/notifications/mark_reply_read.rs @@ -1,10 +1,14 @@ use actix_web::web::{Data, Json}; -use lemmy_api_common::{context::LemmyContext, person::MarkCommentReplyAsRead, SuccessResponse}; +use lemmy_api_common::{ + context::LemmyContext, + person::{CommentReplyResponse, MarkCommentReplyAsRead}, +}; use lemmy_db_schema::{ source::comment_reply::{CommentReply, CommentReplyUpdateForm}, traits::Crud, }; use lemmy_db_views::structs::LocalUserView; +use lemmy_db_views_actor::structs::CommentReplyView; use lemmy_utils::error::{LemmyError, LemmyErrorExt, LemmyErrorType}; #[tracing::instrument(skip(context))] @@ -12,7 +16,7 @@ pub async fn mark_reply_as_read( data: Json, context: Data, local_user_view: LocalUserView, -) -> Result, LemmyError> { +) -> Result, LemmyError> { let comment_reply_id = data.comment_reply_id; let read_comment_reply = CommentReply::read(&mut context.pool(), comment_reply_id).await?; @@ -31,5 +35,10 @@ pub async fn mark_reply_as_read( .await .with_lemmy_type(LemmyErrorType::CouldntUpdateComment)?; - Ok(Json(SuccessResponse::default())) + let comment_reply_id = read_comment_reply.id; + let person_id = local_user_view.person.id; + let comment_reply_view = + CommentReplyView::read(&mut context.pool(), comment_reply_id, Some(person_id)).await?; + + Ok(Json(CommentReplyResponse { comment_reply_view })) } diff --git a/crates/api/src/site/block.rs b/crates/api/src/site/block.rs index 6cf220038..be48e8ce8 100644 --- a/crates/api/src/site/block.rs +++ b/crates/api/src/site/block.rs @@ -1,6 +1,9 @@ use activitypub_federation::config::Data; use actix_web::web::Json; -use lemmy_api_common::{context::LemmyContext, site::BlockInstance, SuccessResponse}; +use lemmy_api_common::{ + context::LemmyContext, + site::{BlockInstance, BlockInstanceResponse}, +}; use lemmy_db_schema::{ source::instance_block::{InstanceBlock, InstanceBlockForm}, traits::Blockable, @@ -13,7 +16,7 @@ pub async fn block_instance( data: Json, local_user_view: LocalUserView, context: Data, -) -> Result, LemmyError> { +) -> Result, LemmyError> { let instance_id = data.instance_id; let person_id = local_user_view.person.id; let instance_block_form = InstanceBlockForm { @@ -31,5 +34,7 @@ pub async fn block_instance( .with_lemmy_type(LemmyErrorType::InstanceBlockAlreadyExists)?; } - Ok(Json(SuccessResponse::default())) + Ok(Json(BlockInstanceResponse { + blocked: data.block, + })) } diff --git a/crates/api_common/src/community.rs b/crates/api_common/src/community.rs index dab69e711..8e87ab750 100644 --- a/crates/api_common/src/community.rs +++ b/crates/api_common/src/community.rs @@ -4,7 +4,7 @@ use lemmy_db_schema::{ ListingType, SortType, }; -use lemmy_db_views_actor::structs::{CommunityModeratorView, CommunityView}; +use lemmy_db_views_actor::structs::{CommunityModeratorView, CommunityView, PersonView}; use serde::{Deserialize, Serialize}; use serde_with::skip_serializing_none; #[cfg(feature = "full")] @@ -100,6 +100,15 @@ pub struct BanFromCommunity { pub expires: Option, } +#[derive(Debug, Serialize, Deserialize, Clone)] +#[cfg_attr(feature = "full", derive(TS))] +#[cfg_attr(feature = "full", ts(export))] +/// The response for banning a user from a community. +pub struct BanFromCommunityResponse { + pub person_view: PersonView, + pub banned: bool, +} + #[derive(Debug, Serialize, Deserialize, Clone, Default)] #[cfg_attr(feature = "full", derive(TS))] #[cfg_attr(feature = "full", ts(export))] @@ -110,6 +119,14 @@ pub struct AddModToCommunity { pub added: bool, } +#[derive(Debug, Serialize, Deserialize, Clone)] +#[cfg_attr(feature = "full", derive(TS))] +#[cfg_attr(feature = "full", ts(export))] +/// The response of adding a moderator to a community. +pub struct AddModToCommunityResponse { + pub moderators: Vec, +} + #[skip_serializing_none] #[derive(Debug, Serialize, Deserialize, Clone, Default)] #[cfg_attr(feature = "full", derive(TS))] @@ -183,6 +200,16 @@ pub struct BlockCommunity { pub block: bool, } +#[skip_serializing_none] +#[derive(Debug, Serialize, Deserialize, Clone)] +#[cfg_attr(feature = "full", derive(TS))] +#[cfg_attr(feature = "full", ts(export))] +/// The block community response. +pub struct BlockCommunityResponse { + pub community_view: CommunityView, + pub blocked: bool, +} + #[derive(Debug, Serialize, Deserialize, Clone, Default)] #[cfg_attr(feature = "full", derive(TS))] #[cfg_attr(feature = "full", ts(export))] diff --git a/crates/api_common/src/person.rs b/crates/api_common/src/person.rs index 9642821c4..c067c3799 100644 --- a/crates/api_common/src/person.rs +++ b/crates/api_common/src/person.rs @@ -193,6 +193,14 @@ pub struct AddAdmin { pub added: bool, } +#[derive(Debug, Serialize, Deserialize, Clone)] +#[cfg_attr(feature = "full", derive(TS))] +#[cfg_attr(feature = "full", ts(export))] +/// The response of current admins. +pub struct AddAdminResponse { + pub admins: Vec, +} + #[skip_serializing_none] #[derive(Debug, Serialize, Deserialize, Clone, Default)] #[cfg_attr(feature = "full", derive(TS))] @@ -216,6 +224,15 @@ pub struct BannedPersonsResponse { pub banned: Vec, } +#[derive(Debug, Serialize, Deserialize, Clone)] +#[cfg_attr(feature = "full", derive(TS))] +#[cfg_attr(feature = "full", ts(export))] +/// A response for a banned person. +pub struct BanPersonResponse { + pub person_view: PersonView, + pub banned: bool, +} + #[derive(Debug, Serialize, Deserialize, Clone, Default)] #[cfg_attr(feature = "full", derive(TS))] #[cfg_attr(feature = "full", ts(export))] @@ -225,6 +242,15 @@ pub struct BlockPerson { pub block: bool, } +#[derive(Debug, Serialize, Deserialize, Clone)] +#[cfg_attr(feature = "full", derive(TS))] +#[cfg_attr(feature = "full", ts(export))] +/// The response for a person block. +pub struct BlockPersonResponse { + pub person_view: PersonView, + pub blocked: bool, +} + #[skip_serializing_none] #[derive(Debug, Serialize, Deserialize, Clone, Default)] #[cfg_attr(feature = "full", derive(TS))] @@ -292,6 +318,14 @@ pub struct MarkCommentReplyAsRead { pub read: bool, } +#[derive(Debug, Serialize, Deserialize, Clone)] +#[cfg_attr(feature = "full", derive(TS))] +#[cfg_attr(feature = "full", ts(export))] +/// The response for a comment reply action. +pub struct CommentReplyResponse { + pub comment_reply_view: CommentReplyView, +} + #[derive(Debug, Serialize, Deserialize, Clone, Default)] #[cfg_attr(feature = "full", derive(TS))] #[cfg_attr(feature = "full", ts(export))] diff --git a/crates/api_common/src/site.rs b/crates/api_common/src/site.rs index a66f20040..d40729e35 100644 --- a/crates/api_common/src/site.rs +++ b/crates/api_common/src/site.rs @@ -416,3 +416,11 @@ pub struct BlockInstance { pub instance_id: InstanceId, pub block: bool, } + +#[skip_serializing_none] +#[derive(Debug, Serialize, Deserialize, Clone)] +#[cfg_attr(feature = "full", derive(TS))] +#[cfg_attr(feature = "full", ts(export))] +pub struct BlockInstanceResponse { + pub blocked: bool, +} From cae25486e40bbeada8e13c9b32f4e478017d6955 Mon Sep 17 00:00:00 2001 From: Dessalines Date: Thu, 19 Oct 2023 20:16:12 -0400 Subject: [PATCH 2/6] Adding ts-rs directives for login_token. (#4063) * Adding ts-rs directives for login_token. * Fixing ts-rs derive. --- crates/api/src/community/hide.rs | 8 ++++---- crates/api_common/src/community.rs | 1 - crates/db_schema/src/source/login_token.rs | 7 ++++++- src/api_routes_http.rs | 4 ++-- 4 files changed, 12 insertions(+), 8 deletions(-) diff --git a/crates/api/src/community/hide.rs b/crates/api/src/community/hide.rs index dd8343927..27919a42b 100644 --- a/crates/api/src/community/hide.rs +++ b/crates/api/src/community/hide.rs @@ -1,11 +1,11 @@ use activitypub_federation::config::Data; use actix_web::web::Json; use lemmy_api_common::{ - build_response::build_community_response, - community::{CommunityResponse, HideCommunity}, + community::HideCommunity, context::LemmyContext, send_activity::{ActivityChannel, SendActivityData}, utils::is_admin, + SuccessResponse, }; use lemmy_db_schema::{ source::{ @@ -22,7 +22,7 @@ pub async fn hide_community( data: Json, context: Data, local_user_view: LocalUserView, -) -> Result, LemmyError> { +) -> Result, LemmyError> { // Verify its a admin (only admin can hide or unhide it) is_admin(&local_user_view)?; @@ -51,5 +51,5 @@ pub async fn hide_community( ) .await?; - build_community_response(&context, local_user_view, community_id).await + Ok(Json(SuccessResponse::default())) } diff --git a/crates/api_common/src/community.rs b/crates/api_common/src/community.rs index 8e87ab750..1f4a94636 100644 --- a/crates/api_common/src/community.rs +++ b/crates/api_common/src/community.rs @@ -154,7 +154,6 @@ pub struct EditCommunity { #[cfg_attr(feature = "full", derive(TS))] #[cfg_attr(feature = "full", ts(export))] /// Hide a community from the main view. -// TODO this should really be a part of edit community. And why does it contain a reason, that should be in the mod tables. pub struct HideCommunity { pub community_id: CommunityId, pub hidden: bool, diff --git a/crates/db_schema/src/source/login_token.rs b/crates/db_schema/src/source/login_token.rs index 008b96e04..45f74c41f 100644 --- a/crates/db_schema/src/source/login_token.rs +++ b/crates/db_schema/src/source/login_token.rs @@ -3,11 +3,16 @@ use crate::newtypes::LocalUserId; use crate::schema::login_token; use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; +use serde_with::skip_serializing_none; +#[cfg(feature = "full")] +use ts_rs::TS; /// Stores data related to a specific user login session. +#[skip_serializing_none] #[derive(Clone, PartialEq, Eq, Debug, Serialize, Deserialize)] -#[cfg_attr(feature = "full", derive(Queryable, Identifiable))] +#[cfg_attr(feature = "full", derive(Queryable, Identifiable, TS))] #[cfg_attr(feature = "full", diesel(table_name = login_token))] +#[cfg_attr(feature = "full", ts(export))] pub struct LoginToken { pub id: i32, /// Jwt token for this login diff --git a/src/api_routes_http.rs b/src/api_routes_http.rs index 26d6b9e8d..fb784b3b3 100644 --- a/src/api_routes_http.rs +++ b/src/api_routes_http.rs @@ -275,7 +275,7 @@ pub fn config(cfg: &mut web::ServiceConfig, rate_limit: &RateLimitCell) { .route("/ban", web::post().to(ban_from_site)) .route("/banned", web::get().to(list_banned_users)) .route("/block", web::post().to(block_person)) - // Account actions. I don't like that they're in /user maybe /accounts + // TODO Account actions. I don't like that they're in /user maybe /accounts .route("/login", web::post().to(login)) .route("/logout", web::post().to(logout)) .route("/delete_account", web::post().to(delete_account)) @@ -284,7 +284,7 @@ pub fn config(cfg: &mut web::ServiceConfig, rate_limit: &RateLimitCell) { "/password_change", web::post().to(change_password_after_reset), ) - // mark_all_as_read feels off being in this section as well + // TODO mark_all_as_read feels off being in this section as well .route( "/mark_all_as_read", web::post().to(mark_all_notifications_read), From 236c7e24fd27bd49169fbd4072dbb92cfc078498 Mon Sep 17 00:00:00 2001 From: Dessalines Date: Thu, 19 Oct 2023 20:16:23 -0400 Subject: [PATCH 3/6] Making mark post read fields optional. (#4055) * Making mark post read fields optional. * Remove unecessary & * Fix clippy. * Addressing PR comments. * serde(default) * Revert "serde(default)" This reverts commit d56afd3075a3baccb2b0eda1cc739406b83963aa. --------- Co-authored-by: Felix Ableitner --- crates/api/src/post/mark_read.rs | 13 ++++++++++--- crates/api_common/src/post.rs | 5 +++-- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/crates/api/src/post/mark_read.rs b/crates/api/src/post/mark_read.rs index a377b3c6c..a46e949fa 100644 --- a/crates/api/src/post/mark_read.rs +++ b/crates/api/src/post/mark_read.rs @@ -11,14 +11,21 @@ pub async fn mark_post_as_read( context: Data, local_user_view: LocalUserView, ) -> Result, LemmyError> { - let mut post_ids = data.post_ids.iter().cloned().collect::>(); - post_ids.insert(data.post_id); - let person_id = local_user_view.person.id; + let mut post_ids = HashSet::new(); + if let Some(post_ids_) = &data.post_ids { + post_ids.extend(post_ids_.iter().cloned()); + } + + if let Some(post_id) = data.post_id { + post_ids.insert(post_id); + } if post_ids.len() > MAX_API_PARAM_ELEMENTS { Err(LemmyErrorType::TooManyItems)?; } + let person_id = local_user_view.person.id; + // Mark the post as read / unread if data.read { PostRead::mark_as_read(&mut context.pool(), post_ids, person_id) diff --git a/crates/api_common/src/post.rs b/crates/api_common/src/post.rs index fbb6f1d38..b93742bea 100644 --- a/crates/api_common/src/post.rs +++ b/crates/api_common/src/post.rs @@ -135,14 +135,15 @@ pub struct RemovePost { pub reason: Option, } +#[skip_serializing_none] #[derive(Debug, Serialize, Deserialize, Clone, Default)] #[cfg_attr(feature = "full", derive(TS))] #[cfg_attr(feature = "full", ts(export))] /// Mark a post as read. pub struct MarkPostAsRead { /// TODO: deprecated, send `post_ids` instead - pub post_id: PostId, - pub post_ids: Vec, + pub post_id: Option, + pub post_ids: Option>, pub read: bool, } From 6bcb12b14f056b8994feb39d8c30251ee26196ca Mon Sep 17 00:00:00 2001 From: Dessalines Date: Thu, 19 Oct 2023 20:34:48 -0400 Subject: [PATCH 4/6] Version 0.19.0-rc.3 --- Cargo.lock | 24 ++++++++++++------------ Cargo.toml | 24 ++++++++++++------------ crates/utils/translations | 2 +- 3 files changed, 25 insertions(+), 25 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 073e0a95c..de86ce622 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2621,7 +2621,7 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "lemmy_api" -version = "0.19.0-rc.2" +version = "0.19.0-rc.3" dependencies = [ "activitypub_federation", "actix-web", @@ -2652,7 +2652,7 @@ dependencies = [ [[package]] name = "lemmy_api_common" -version = "0.19.0-rc.2" +version = "0.19.0-rc.3" dependencies = [ "activitypub_federation", "actix-web", @@ -2687,7 +2687,7 @@ dependencies = [ [[package]] name = "lemmy_api_crud" -version = "0.19.0-rc.2" +version = "0.19.0-rc.3" dependencies = [ "activitypub_federation", "actix-web", @@ -2708,7 +2708,7 @@ dependencies = [ [[package]] name = "lemmy_apub" -version = "0.19.0-rc.2" +version = "0.19.0-rc.3" dependencies = [ "activitypub_federation", "actix-web", @@ -2747,7 +2747,7 @@ dependencies = [ [[package]] name = "lemmy_db_schema" -version = "0.19.0-rc.2" +version = "0.19.0-rc.3" dependencies = [ "activitypub_federation", "async-trait", @@ -2783,7 +2783,7 @@ dependencies = [ [[package]] name = "lemmy_db_views" -version = "0.19.0-rc.2" +version = "0.19.0-rc.3" dependencies = [ "actix-web", "diesel", @@ -2801,7 +2801,7 @@ dependencies = [ [[package]] name = "lemmy_db_views_actor" -version = "0.19.0-rc.2" +version = "0.19.0-rc.3" dependencies = [ "chrono", "diesel", @@ -2816,7 +2816,7 @@ dependencies = [ [[package]] name = "lemmy_db_views_moderator" -version = "0.19.0-rc.2" +version = "0.19.0-rc.3" dependencies = [ "diesel", "diesel-async", @@ -2828,7 +2828,7 @@ dependencies = [ [[package]] name = "lemmy_federate" -version = "0.19.0-rc.2" +version = "0.19.0-rc.3" dependencies = [ "activitypub_federation", "anyhow", @@ -2860,7 +2860,7 @@ dependencies = [ [[package]] name = "lemmy_routes" -version = "0.19.0-rc.2" +version = "0.19.0-rc.3" dependencies = [ "activitypub_federation", "actix-web", @@ -2885,7 +2885,7 @@ dependencies = [ [[package]] name = "lemmy_server" -version = "0.19.0-rc.2" +version = "0.19.0-rc.3" dependencies = [ "activitypub_federation", "actix-cors", @@ -2933,7 +2933,7 @@ dependencies = [ [[package]] name = "lemmy_utils" -version = "0.19.0-rc.2" +version = "0.19.0-rc.3" dependencies = [ "actix-web", "anyhow", diff --git a/Cargo.toml b/Cargo.toml index 9bf1000b6..a01cc687b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,5 @@ [workspace.package] -version = "0.19.0-rc.2" +version = "0.19.0-rc.3" edition = "2021" description = "A link aggregator for the fediverse" license = "AGPL-3.0" @@ -60,16 +60,16 @@ members = [ ] [workspace.dependencies] -lemmy_api = { version = "=0.19.0-rc.2", path = "./crates/api" } -lemmy_api_crud = { version = "=0.19.0-rc.2", path = "./crates/api_crud" } -lemmy_apub = { version = "=0.19.0-rc.2", path = "./crates/apub" } -lemmy_utils = { version = "=0.19.0-rc.2", path = "./crates/utils" } -lemmy_db_schema = { version = "=0.19.0-rc.2", path = "./crates/db_schema" } -lemmy_api_common = { version = "=0.19.0-rc.2", path = "./crates/api_common" } -lemmy_routes = { version = "=0.19.0-rc.2", path = "./crates/routes" } -lemmy_db_views = { version = "=0.19.0-rc.2", path = "./crates/db_views" } -lemmy_db_views_actor = { version = "=0.19.0-rc.2", path = "./crates/db_views_actor" } -lemmy_db_views_moderator = { version = "=0.19.0-rc.2", path = "./crates/db_views_moderator" } +lemmy_api = { version = "=0.19.0-rc.3", path = "./crates/api" } +lemmy_api_crud = { version = "=0.19.0-rc.3", path = "./crates/api_crud" } +lemmy_apub = { version = "=0.19.0-rc.3", path = "./crates/apub" } +lemmy_utils = { version = "=0.19.0-rc.3", path = "./crates/utils" } +lemmy_db_schema = { version = "=0.19.0-rc.3", path = "./crates/db_schema" } +lemmy_api_common = { version = "=0.19.0-rc.3", path = "./crates/api_common" } +lemmy_routes = { version = "=0.19.0-rc.3", path = "./crates/routes" } +lemmy_db_views = { version = "=0.19.0-rc.3", path = "./crates/db_views" } +lemmy_db_views_actor = { version = "=0.19.0-rc.3", path = "./crates/db_views_actor" } +lemmy_db_views_moderator = { version = "=0.19.0-rc.3", path = "./crates/db_views_moderator" } activitypub_federation = { version = "0.5.0-beta.3", default-features = false, features = [ "actix-web", ] } @@ -139,7 +139,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-rc.2", path = "crates/federate" } +lemmy_federate = { version = "0.19.0-rc.3", path = "crates/federate" } activitypub_federation = { workspace = true } diesel = { workspace = true } diesel-async = { workspace = true } diff --git a/crates/utils/translations b/crates/utils/translations index d0f354837..abd40d473 160000 --- a/crates/utils/translations +++ b/crates/utils/translations @@ -1 +1 @@ -Subproject commit d0f3548379e446d2c333e582734bc68f8d684f4d +Subproject commit abd40d4737fa732321fd7b62e42bbfcd51081cb6 From dfc74835b1dc6d5bc85ef8fa06e734a9c115bbe1 Mon Sep 17 00:00:00 2001 From: Nutomic Date: Fri, 20 Oct 2023 16:01:29 +0200 Subject: [PATCH 5/6] Hide deleted user accounts, add tests for PersonView (fixes #3811) (#4070) * Hide deleted user accounts, add tests for PersonView (fixes #3811) * clippy --- Cargo.lock | 2 + crates/db_views_actor/Cargo.toml | 4 + crates/db_views_actor/src/person_view.rs | 163 +++++++++++++++++++++++ 3 files changed, 169 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index de86ce622..378f6cb2e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2809,8 +2809,10 @@ dependencies = [ "lemmy_db_schema", "serde", "serde_with", + "serial_test", "strum", "strum_macros", + "tokio", "ts-rs", ] diff --git a/crates/db_views_actor/Cargo.toml b/crates/db_views_actor/Cargo.toml index 358bf0cab..93ce0f5b3 100644 --- a/crates/db_views_actor/Cargo.toml +++ b/crates/db_views_actor/Cargo.toml @@ -31,3 +31,7 @@ ts-rs = { workspace = true, optional = true } chrono.workspace = true strum = { workspace = true } strum_macros = { workspace = true } + +[dev-dependencies] +serial_test = { workspace = true } +tokio = { workspace = true } diff --git a/crates/db_views_actor/src/person_view.rs b/crates/db_views_actor/src/person_view.rs index d06654f98..9e7c4d7e6 100644 --- a/crates/db_views_actor/src/person_view.rs +++ b/crates/db_views_actor/src/person_view.rs @@ -52,6 +52,7 @@ fn queries<'a>( query .inner_join(person_aggregates::table) .left_join(local_user::table) + .filter(person::deleted.eq(false)) .select((person::all_columns, person_aggregates::all_columns)) }; @@ -151,3 +152,165 @@ impl PersonQuery { queries().list(pool, ListMode::Query(self)).await } } + +#[cfg(test)] +mod tests { + #![allow(clippy::unwrap_used)] + #![allow(clippy::indexing_slicing)] + + use super::*; + use diesel::NotFound; + use lemmy_db_schema::{ + source::{ + instance::Instance, + local_user::{LocalUser, LocalUserInsertForm, LocalUserUpdateForm}, + person::{Person, PersonInsertForm, PersonUpdateForm}, + }, + traits::Crud, + utils::build_db_pool_for_tests, + }; + use serial_test::serial; + + struct Data { + alice: Person, + alice_local_user: LocalUser, + bob: Person, + bob_local_user: LocalUser, + } + + async fn init_data(pool: &mut DbPool<'_>) -> Data { + let inserted_instance = Instance::read_or_create(pool, "my_domain.tld".to_string()) + .await + .unwrap(); + + let alice_form = PersonInsertForm::builder() + .name("alice".to_string()) + .public_key("pubkey".to_string()) + .instance_id(inserted_instance.id) + .build(); + let alice = Person::create(pool, &alice_form).await.unwrap(); + let alice_local_user_form = LocalUserInsertForm::builder() + .person_id(alice.id) + .password_encrypted(String::new()) + .build(); + let alice_local_user = LocalUser::create(pool, &alice_local_user_form) + .await + .unwrap(); + + let bob_form = PersonInsertForm::builder() + .name("bob".to_string()) + .bot_account(Some(true)) + .public_key("pubkey".to_string()) + .instance_id(inserted_instance.id) + .build(); + let bob = Person::create(pool, &bob_form).await.unwrap(); + let bob_local_user_form = LocalUserInsertForm::builder() + .person_id(bob.id) + .password_encrypted(String::new()) + .build(); + let bob_local_user = LocalUser::create(pool, &bob_local_user_form).await.unwrap(); + + Data { + alice, + alice_local_user, + bob, + bob_local_user, + } + } + + async fn cleanup(data: Data, pool: &mut DbPool<'_>) { + LocalUser::delete(pool, data.alice_local_user.id) + .await + .unwrap(); + LocalUser::delete(pool, data.bob_local_user.id) + .await + .unwrap(); + Person::delete(pool, data.alice.id).await.unwrap(); + Person::delete(pool, data.bob.id).await.unwrap(); + Instance::delete(pool, data.bob.instance_id).await.unwrap(); + } + + #[tokio::test] + #[serial] + async fn exclude_deleted() { + let pool = &build_db_pool_for_tests().await; + let pool = &mut pool.into(); + let data = init_data(pool).await; + + Person::update( + pool, + data.alice.id, + &PersonUpdateForm { + deleted: Some(true), + ..Default::default() + }, + ) + .await + .unwrap(); + + let read = PersonView::read(pool, data.alice.id).await; + assert_eq!(read.err(), Some(NotFound)); + + let list = PersonQuery::default().list(pool).await.unwrap(); + assert_eq!(list.len(), 1); + assert_eq!(list[0].person.id, data.bob.id); + + cleanup(data, pool).await; + } + + #[tokio::test] + #[serial] + async fn list_banned() { + let pool = &build_db_pool_for_tests().await; + let pool = &mut pool.into(); + let data = init_data(pool).await; + + Person::update( + pool, + data.alice.id, + &PersonUpdateForm { + banned: Some(true), + ..Default::default() + }, + ) + .await + .unwrap(); + + let list = PersonView::banned(pool).await.unwrap(); + assert_eq!(list.len(), 1); + assert_eq!(list[0].person.id, data.alice.id); + + cleanup(data, pool).await; + } + + #[tokio::test] + #[serial] + async fn list_admins() { + let pool = &build_db_pool_for_tests().await; + let pool = &mut pool.into(); + let data = init_data(pool).await; + + LocalUser::update( + pool, + data.alice_local_user.id, + &LocalUserUpdateForm { + admin: Some(true), + ..Default::default() + }, + ) + .await + .unwrap(); + + let list = PersonView::admins(pool).await.unwrap(); + assert_eq!(list.len(), 1); + assert_eq!(list[0].person.id, data.alice.id); + + let is_admin = PersonView::is_admin(pool, data.alice.id).await.unwrap(); + assert!(is_admin); + + let is_admin = PersonView::is_admin(pool, data.bob.id).await.unwrap(); + assert!(!is_admin); + + cleanup(data, pool).await; + } +} From ec0a707110dc4f8641bdfeda8595159a81272259 Mon Sep 17 00:00:00 2001 From: Nutomic Date: Fri, 20 Oct 2023 17:09:34 +0200 Subject: [PATCH 6/6] Avoid using proxy for pictrs requests (fixes #3489) (#4072) * Avoid using proxy for pictrs requests (fixes #3489) * fmt --- crates/api_common/src/request.rs | 25 ++++++++---------- crates/apub/src/objects/mod.rs | 10 +++---- docker/docker-compose.yml | 2 +- docker/docker_update.sh | 4 +-- src/lib.rs | 45 ++++++++++++-------------------- 5 files changed, 33 insertions(+), 53 deletions(-) diff --git a/crates/api_common/src/request.rs b/crates/api_common/src/request.rs index b27bf2e92..0064c8045 100644 --- a/crates/api_common/src/request.rs +++ b/crates/api_common/src/request.rs @@ -8,6 +8,7 @@ use lemmy_utils::{ REQWEST_TIMEOUT, }; use percent_encoding::{utf8_percent_encode, NON_ALPHANUMERIC}; +use reqwest::{Client, ClientBuilder}; use reqwest_middleware::ClientWithMiddleware; use serde::Deserialize; use tracing::info; @@ -288,12 +289,17 @@ async fn is_image_content_type(client: &ClientWithMiddleware, url: &Url) -> Resu } } -pub fn build_user_agent(settings: &Settings) -> String { - format!( +pub fn client_builder(settings: &Settings) -> ClientBuilder { + let user_agent = format!( "Lemmy/{}; +{}", VERSION, settings.get_protocol_and_hostname() - ) + ); + + Client::builder() + .user_agent(user_agent.clone()) + .timeout(REQWEST_TIMEOUT) + .connect_timeout(REQWEST_TIMEOUT) } #[cfg(test)] @@ -301,12 +307,7 @@ mod tests { #![allow(clippy::unwrap_used)] #![allow(clippy::indexing_slicing)] - use crate::request::{ - build_user_agent, - fetch_site_metadata, - html_to_site_metadata, - SiteMetadata, - }; + use crate::request::{client_builder, fetch_site_metadata, html_to_site_metadata, SiteMetadata}; use lemmy_utils::settings::SETTINGS; use url::Url; @@ -314,11 +315,7 @@ mod tests { #[tokio::test] async fn test_site_metadata() { let settings = &SETTINGS.clone(); - let client = reqwest::Client::builder() - .user_agent(build_user_agent(settings)) - .build() - .unwrap() - .into(); + let client = client_builder(settings).build().unwrap().into(); let sample_url = Url::parse("https://gitlab.com/IzzyOnDroid/repo/-/wikis/FAQ").unwrap(); let sample_res = fetch_site_metadata(&client, &sample_url).await.unwrap(); assert_eq!( diff --git a/crates/apub/src/objects/mod.rs b/crates/apub/src/objects/mod.rs index 6e27c0d09..116c7f4fb 100644 --- a/crates/apub/src/objects/mod.rs +++ b/crates/apub/src/objects/mod.rs @@ -59,10 +59,10 @@ pub(crate) mod tests { use activitypub_federation::config::{Data, FederationConfig}; use anyhow::anyhow; - use lemmy_api_common::{context::LemmyContext, request::build_user_agent}; + use lemmy_api_common::{context::LemmyContext, request::client_builder}; use lemmy_db_schema::{source::secret::Secret, utils::build_db_pool_for_tests}; use lemmy_utils::{rate_limit::RateLimitCell, settings::SETTINGS}; - use reqwest::{Client, Request, Response}; + use reqwest::{Request, Response}; use reqwest_middleware::{ClientBuilder, Middleware, Next}; use task_local_extensions::Extensions; @@ -86,11 +86,7 @@ pub(crate) mod tests { // call this to run migrations let pool = build_db_pool_for_tests().await; - let settings = SETTINGS.clone(); - let client = Client::builder() - .user_agent(build_user_agent(&settings)) - .build() - .unwrap(); + let client = client_builder(&SETTINGS).build().unwrap(); let client = ClientBuilder::new(client).with(BlockedMiddleware).build(); let secret = Secret { diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index a61f25973..bd339aabb 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -55,7 +55,7 @@ services: lemmy-ui: # use "image" to pull down an already compiled lemmy-ui. make sure to comment out "build". - image: dessalines/lemmy-ui:0.18.4 + image: dessalines/lemmy-ui:0.19.0-rc.3 # platform: linux/x86_64 # no arm64 support. uncomment platform if using m1. # use "build" to build your local lemmy ui image for development. make sure to comment out "image". # run: docker compose up --build diff --git a/docker/docker_update.sh b/docker/docker_update.sh index d64025cc1..45411f1a3 100755 --- a/docker/docker_update.sh +++ b/docker/docker_update.sh @@ -45,9 +45,9 @@ if [ "$ARCH" = 'arm64' ]; then fi echo "$LOG_PREFIX Initializing images in the background. Please be patient if compiling from source..." - docker compose up -d --build + docker compose up --build else - sudo docker compose up -d --build + sudo docker compose up --build fi echo "$LOG_PREFIX Complete! You can now access the UI at http://localhost:1236." diff --git a/src/lib.rs b/src/lib.rs index 2df231dd5..c12281cdf 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -28,7 +28,7 @@ use clap::{ArgAction, Parser}; use lemmy_api_common::{ context::LemmyContext, lemmy_db_views::structs::SiteView, - request::build_user_agent, + request::client_builder, send_activity::{ActivityChannel, MATCH_OUTGOING_ACTIVITIES}, utils::{ check_private_instance_and_federation_enabled, @@ -52,11 +52,10 @@ use lemmy_utils::{ response::jsonify_plain_text_errors, settings::{structs::Settings, SETTINGS}, }; -use reqwest::Client; use reqwest_middleware::{ClientBuilder, ClientWithMiddleware}; use reqwest_tracing::TracingMiddleware; use serde_json::json; -use std::{env, ops::Deref, time::Duration}; +use std::{env, ops::Deref}; use tokio::signal::unix::SignalKind; use tracing::subscriber::set_global_default; use tracing_actix_web::TracingLogger; @@ -112,13 +111,9 @@ pub struct CmdArgs { #[arg(long, default_value_t = 1)] federate_process_count: i32, } -/// Max timeout for http requests -pub(crate) const REQWEST_TIMEOUT: Duration = Duration::from_secs(10); /// Placing the main function in lib.rs allows other crates to import it and embed Lemmy pub async fn start_lemmy_server(args: CmdArgs) -> Result<(), LemmyError> { - let settings = SETTINGS.to_owned(); - // return error 503 while running db migrations and startup tasks let mut startup_server_handle = None; if args.http_server { @@ -126,14 +121,14 @@ pub async fn start_lemmy_server(args: CmdArgs) -> Result<(), LemmyError> { } // Run the DB migrations - let db_url = get_database_url(Some(&settings)); + let db_url = get_database_url(Some(&SETTINGS)); run_migrations(&db_url); // Set up the connection pool - let pool = build_db_pool(&settings).await?; + let pool = build_db_pool(&SETTINGS).await?; // Run the Code-required migrations - run_advanced_migrations(&mut (&pool).into(), &settings).await?; + run_advanced_migrations(&mut (&pool).into(), &SETTINGS).await?; // Initialize the secrets let secret = Secret::init(&mut (&pool).into()) @@ -148,7 +143,7 @@ pub async fn start_lemmy_server(args: CmdArgs) -> Result<(), LemmyError> { let federation_enabled = local_site.federation_enabled; if federation_enabled { - println!("federation enabled, host is {}", &settings.hostname); + println!("federation enabled, host is {}", &SETTINGS.hostname); } check_private_instance_and_federation_enabled(&local_site)?; @@ -160,25 +155,12 @@ pub async fn start_lemmy_server(args: CmdArgs) -> Result<(), LemmyError> { println!( "Starting http server at {}:{}", - settings.bind, settings.port + SETTINGS.bind, SETTINGS.port ); - let user_agent = build_user_agent(&settings); - let reqwest_client = Client::builder() - .user_agent(user_agent.clone()) - .timeout(REQWEST_TIMEOUT) - .connect_timeout(REQWEST_TIMEOUT) - .build()?; - - let client = ClientBuilder::new(reqwest_client.clone()) + let client = ClientBuilder::new(client_builder(&SETTINGS).build()?) .with(TracingMiddleware::default()) .build(); - - // Pictrs cannot use the retry middleware - let pictrs_client = ClientBuilder::new(reqwest_client.clone()) - .with(TracingMiddleware::default()) - .build(); - let context = LemmyContext::create( pool.clone(), client.clone(), @@ -192,10 +174,10 @@ pub async fn start_lemmy_server(args: CmdArgs) -> Result<(), LemmyError> { } #[cfg(feature = "prometheus-metrics")] - serve_prometheus(settings.prometheus.as_ref(), context.clone()); + serve_prometheus(SETTINGS.prometheus.as_ref(), context.clone()); let federation_config = FederationConfig::builder() - .domain(settings.hostname.clone()) + .domain(SETTINGS.hostname.clone()) .app_data(context.clone()) .client(client.clone()) .http_fetch_limit(FEDERATION_HTTP_FETCH_LIMIT) @@ -217,9 +199,14 @@ pub async fn start_lemmy_server(args: CmdArgs) -> Result<(), LemmyError> { if let Some(startup_server_handle) = startup_server_handle { startup_server_handle.stop(true).await; } + + // Pictrs cannot use proxy + let pictrs_client = ClientBuilder::new(client_builder(&SETTINGS).no_proxy().build()?) + .with(TracingMiddleware::default()) + .build(); Some(create_http_server( federation_config.clone(), - settings.clone(), + SETTINGS.clone(), federation_enabled, pictrs_client, )?)