]> Untitled Git - lemmy.git/commitdiff
Merge pull request #1937 from LemmyNet/disable-edit-email-notifications
authorDessalines <dessalines@users.noreply.github.com>
Thu, 25 Nov 2021 18:00:26 +0000 (13:00 -0500)
committerGitHub <noreply@github.com>
Thu, 25 Nov 2021 18:00:26 +0000 (13:00 -0500)
Dont send email notifications for edited comments (fixes #1925)

34 files changed:
Cargo.lock
Cargo.toml
crates/api/Cargo.toml
crates/api/src/lib.rs
crates/api/src/post.rs
crates/api_common/Cargo.toml
crates/api_common/src/comment.rs
crates/api_common/src/lib.rs
crates/api_common/src/post.rs
crates/api_crud/Cargo.toml
crates/api_crud/src/comment/read.rs
crates/api_crud/src/lib.rs
crates/apub/Cargo.toml
crates/apub_lib/Cargo.toml
crates/apub_lib_derive/Cargo.toml
crates/db_schema/Cargo.toml
crates/db_views/Cargo.toml
crates/db_views/src/comment_report_view.rs
crates/db_views/src/post_report_view.rs
crates/db_views_actor/Cargo.toml
crates/db_views_moderator/Cargo.toml
crates/routes/Cargo.toml
crates/utils/Cargo.toml
crates/utils/src/utils.rs
crates/websocket/Cargo.toml
crates/websocket/src/chat_server.rs
crates/websocket/src/lib.rs
docker/dev/docker-compose.yml
docker/federation/docker-compose.yml
docker/prod/docker-compose.yml
migrations/2021-11-22-135324_add_activity_ap_id_index/up.sql
migrations/2021-11-23-031528_add_report_published_index/down.sql [new file with mode: 0644]
migrations/2021-11-23-031528_add_report_published_index/up.sql [new file with mode: 0644]
src/api_routes.rs

index a5b5c86c51267abbca5df5c1f6e324766d40172d..d6fd15a7fc381320f7525e562f8c0e75767c95c8 100644 (file)
@@ -1722,7 +1722,7 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
 
 [[package]]
 name = "lemmy_api"
-version = "0.14.1"
+version = "0.14.3"
 dependencies = [
  "actix",
  "actix-rt",
@@ -1765,7 +1765,7 @@ dependencies = [
 
 [[package]]
 name = "lemmy_api_common"
-version = "0.14.1"
+version = "0.14.3"
 dependencies = [
  "actix-web",
  "chrono",
@@ -1782,7 +1782,7 @@ dependencies = [
 
 [[package]]
 name = "lemmy_api_crud"
-version = "0.14.1"
+version = "0.14.3"
 dependencies = [
  "actix",
  "actix-rt",
@@ -1826,7 +1826,7 @@ dependencies = [
 
 [[package]]
 name = "lemmy_apub"
-version = "0.14.1"
+version = "0.14.3"
 dependencies = [
  "activitystreams-kinds",
  "actix",
@@ -1872,7 +1872,7 @@ dependencies = [
 
 [[package]]
 name = "lemmy_apub_lib"
-version = "0.14.1"
+version = "0.14.3"
 dependencies = [
  "activitystreams",
  "actix-web",
@@ -1898,7 +1898,7 @@ dependencies = [
 
 [[package]]
 name = "lemmy_apub_lib_derive"
-version = "0.14.1"
+version = "0.14.3"
 dependencies = [
  "proc-macro2 1.0.32",
  "quote 1.0.10",
@@ -1908,7 +1908,7 @@ dependencies = [
 
 [[package]]
 name = "lemmy_db_schema"
-version = "0.14.1"
+version = "0.14.3"
 dependencies = [
  "bcrypt",
  "chrono",
@@ -1930,7 +1930,7 @@ dependencies = [
 
 [[package]]
 name = "lemmy_db_views"
-version = "0.14.1"
+version = "0.14.3"
 dependencies = [
  "diesel",
  "lemmy_db_schema",
@@ -1942,7 +1942,7 @@ dependencies = [
 
 [[package]]
 name = "lemmy_db_views_actor"
-version = "0.14.1"
+version = "0.14.3"
 dependencies = [
  "diesel",
  "lemmy_db_schema",
@@ -1951,7 +1951,7 @@ dependencies = [
 
 [[package]]
 name = "lemmy_db_views_moderator"
-version = "0.14.1"
+version = "0.14.3"
 dependencies = [
  "diesel",
  "lemmy_db_schema",
@@ -1960,7 +1960,7 @@ dependencies = [
 
 [[package]]
 name = "lemmy_routes"
-version = "0.14.1"
+version = "0.14.3"
 dependencies = [
  "actix",
  "actix-http",
@@ -1987,7 +1987,7 @@ dependencies = [
 
 [[package]]
 name = "lemmy_server"
-version = "0.14.1"
+version = "0.14.3"
 dependencies = [
  "activitystreams",
  "actix",
@@ -2029,7 +2029,7 @@ dependencies = [
 
 [[package]]
 name = "lemmy_utils"
-version = "0.14.1"
+version = "0.14.3"
 dependencies = [
  "actix-rt",
  "actix-web",
@@ -2066,7 +2066,7 @@ dependencies = [
 
 [[package]]
 name = "lemmy_websocket"
-version = "0.14.1"
+version = "0.14.3"
 dependencies = [
  "actix",
  "actix-web",
index bd247b7d33aefe0c0ebf3e6aac4782e0a174cd18..1a5c07cb22e8534b3a66e78e0265fcf754e3500c 100644 (file)
@@ -1,6 +1,6 @@
 [package]
 name = "lemmy_server"
-version = "0.14.1"
+version = "0.14.3"
 edition = "2018"
 description = "A link aggregator for the fediverse"
 license = "AGPL-3.0"
@@ -31,18 +31,18 @@ members = [
 ]
 
 [dependencies]
-lemmy_api = { version = "=0.14.1", path = "./crates/api" }
-lemmy_api_crud = { version = "=0.14.1", path = "./crates/api_crud" }
-lemmy_apub = { version = "=0.14.1", path = "./crates/apub" }
-lemmy_apub_lib = { version = "=0.14.1", path = "./crates/apub_lib" }
-lemmy_utils = { version = "=0.14.1", path = "./crates/utils" }
-lemmy_db_schema = { version = "=0.14.1", path = "./crates/db_schema" }
-lemmy_db_views = { version = "=0.14.1", path = "./crates/db_views" }
-lemmy_db_views_moderator = { version = "=0.14.1", path = "./crates/db_views_moderator" }
-lemmy_db_views_actor = { version = "=0.14.1", path = "./crates/db_views_actor" }
-lemmy_api_common = { version = "=0.14.1", path = "crates/api_common" }
-lemmy_websocket = { version = "=0.14.1", path = "./crates/websocket" }
-lemmy_routes = { version = "=0.14.1", path = "./crates/routes" }
+lemmy_api = { version = "=0.14.3", path = "./crates/api" }
+lemmy_api_crud = { version = "=0.14.3", path = "./crates/api_crud" }
+lemmy_apub = { version = "=0.14.3", path = "./crates/apub" }
+lemmy_apub_lib = { version = "=0.14.3", path = "./crates/apub_lib" }
+lemmy_utils = { version = "=0.14.3", path = "./crates/utils" }
+lemmy_db_schema = { version = "=0.14.3", path = "./crates/db_schema" }
+lemmy_db_views = { version = "=0.14.3", path = "./crates/db_views" }
+lemmy_db_views_moderator = { version = "=0.14.3", path = "./crates/db_views_moderator" }
+lemmy_db_views_actor = { version = "=0.14.3", path = "./crates/db_views_actor" }
+lemmy_api_common = { version = "=0.14.3", path = "crates/api_common" }
+lemmy_websocket = { version = "=0.14.3", path = "./crates/websocket" }
+lemmy_routes = { version = "=0.14.3", path = "./crates/routes" }
 diesel = "1.4.8"
 diesel_migrations = "1.4.0"
 chrono = { version = "0.4.19", features = ["serde"] }
index f09c1234d896516c0b8ff48e2aeeb37eae48f4b7..8235914540dec2fb25a9bf8391162c4a845bfd71 100644 (file)
@@ -1,6 +1,6 @@
 [package]
 name = "lemmy_api"
-version = "0.14.1"
+version = "0.14.3"
 edition = "2018"
 description = "A link aggregator for the fediverse"
 license = "AGPL-3.0"
@@ -13,15 +13,15 @@ path = "src/lib.rs"
 doctest = false
 
 [dependencies]
-lemmy_apub = { version = "=0.14.1", path = "../apub" }
-lemmy_apub_lib = { version = "=0.14.1", path = "../apub_lib" }
-lemmy_utils = { version = "=0.14.1", path = "../utils" }
-lemmy_db_schema = { version = "=0.14.1", path = "../db_schema" }
-lemmy_db_views = { version = "=0.14.1", path = "../db_views" }
-lemmy_db_views_moderator = { version = "=0.14.1", path = "../db_views_moderator" }
-lemmy_db_views_actor = { version = "=0.14.1", path = "../db_views_actor" }
-lemmy_api_common = { version = "=0.14.1", path = "../api_common" }
-lemmy_websocket = { version = "=0.14.1", path = "../websocket" }
+lemmy_apub = { version = "=0.14.3", path = "../apub" }
+lemmy_apub_lib = { version = "=0.14.3", path = "../apub_lib" }
+lemmy_utils = { version = "=0.14.3", path = "../utils" }
+lemmy_db_schema = { version = "=0.14.3", path = "../db_schema" }
+lemmy_db_views = { version = "=0.14.3", path = "../db_views" }
+lemmy_db_views_moderator = { version = "=0.14.3", path = "../db_views_moderator" }
+lemmy_db_views_actor = { version = "=0.14.3", path = "../db_views_actor" }
+lemmy_api_common = { version = "=0.14.3", path = "../api_common" }
+lemmy_websocket = { version = "=0.14.3", path = "../websocket" }
 diesel = "1.4.8"
 bcrypt = "0.10.1"
 chrono = { version = "0.4.19", features = ["serde"] }
index 74a3d3037098a86ddc27110080fb28a1759b894e..d535c4678fef51f813b96384d59b3c2858be85ce 100644 (file)
@@ -120,6 +120,9 @@ pub async fn match_websocket_operation(
     UserOperation::CreatePostLike => {
       do_websocket_operation::<CreatePostLike>(context, id, op, data).await
     }
+    UserOperation::MarkPostAsRead => {
+      do_websocket_operation::<MarkPostAsRead>(context, id, op, data).await
+    }
     UserOperation::SavePost => do_websocket_operation::<SavePost>(context, id, op, data).await,
     UserOperation::CreatePostReport => {
       do_websocket_operation::<CreatePostReport>(context, id, op, data).await
index c7acb08fb30da67a2e7e948214ddabe250b3a733..60a580b84830e1fa0fcf61cfe6436ef987b5436c 100644 (file)
@@ -9,6 +9,7 @@ use lemmy_api_common::{
   get_local_user_view_from_jwt,
   is_mod_or_admin,
   mark_post_as_read,
+  mark_post_as_unread,
   post::*,
 };
 use lemmy_apub::{
@@ -118,6 +119,41 @@ impl Perform for CreatePostLike {
   }
 }
 
+#[async_trait::async_trait(?Send)]
+impl Perform for MarkPostAsRead {
+  type Response = PostResponse;
+
+  async fn perform(
+    &self,
+    context: &Data<LemmyContext>,
+    _websocket_id: Option<ConnectionId>,
+  ) -> Result<Self::Response, LemmyError> {
+    let data = self;
+    let local_user_view =
+      get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?;
+
+    let post_id = data.post_id;
+    let person_id = local_user_view.person.id;
+
+    // Mark the post as read / unread
+    if data.read {
+      mark_post_as_read(person_id, post_id, context.pool()).await?;
+    } else {
+      mark_post_as_unread(person_id, post_id, context.pool()).await?;
+    }
+
+    // Fetch it
+    let post_view = blocking(context.pool(), move |conn| {
+      PostView::read(conn, post_id, Some(person_id))
+    })
+    .await??;
+
+    let res = Self::Response { post_view };
+
+    Ok(res)
+  }
+}
+
 #[async_trait::async_trait(?Send)]
 impl Perform for LockPost {
   type Response = PostResponse;
index 9b7c56403c889cc179a54ea24cb56f1052e83dce..93290bb148b1a44eb66a189dfb5873c67a52babe 100644 (file)
@@ -1,6 +1,6 @@
 [package]
 name = "lemmy_api_common"
-version = "0.14.1"
+version = "0.14.3"
 edition = "2018"
 description = "A link aggregator for the fediverse"
 license = "AGPL-3.0"
@@ -13,11 +13,11 @@ path = "src/lib.rs"
 doctest = false
 
 [dependencies]
-lemmy_db_views = { version = "=0.14.1", path = "../db_views" }
-lemmy_db_views_moderator = { version = "=0.14.1", path = "../db_views_moderator" }
-lemmy_db_views_actor = { version = "=0.14.1", path = "../db_views_actor" }
-lemmy_db_schema = { version = "=0.14.1", path = "../db_schema" }
-lemmy_utils = { version = "=0.14.1", path = "../utils" }
+lemmy_db_views = { version = "=0.14.3", path = "../db_views" }
+lemmy_db_views_moderator = { version = "=0.14.3", path = "../db_views_moderator" }
+lemmy_db_views_actor = { version = "=0.14.3", path = "../db_views_actor" }
+lemmy_db_schema = { version = "=0.14.3", path = "../db_schema" }
+lemmy_utils = { version = "=0.14.3", path = "../utils" }
 serde = { version = "1.0.130", features = ["derive"] }
 diesel = "1.4.8"
 actix-web = { version = "4.0.0-beta.9", default-features = false, features = ["cookies"] }
index eadbceb2bb0d9234e9e8d26df2e1e89d7b166076..afe76a9950dca74f14622da116636d4af7b7554a 100644 (file)
@@ -11,6 +11,12 @@ pub struct CreateComment {
   pub auth: String,
 }
 
+#[derive(Serialize, Deserialize)]
+pub struct GetComment {
+  pub id: CommentId,
+  pub auth: Option<String>,
+}
+
 #[derive(Serialize, Deserialize)]
 pub struct EditComment {
   pub content: String,
index bf6246a0dc087f67307bba8d410b773265e27487..f5b6ebad27a27264c0421c88571cbcf1f67e1dab 100644 (file)
@@ -81,7 +81,21 @@ pub async fn mark_post_as_read(
     PostRead::mark_as_read(conn, &post_read_form)
   })
   .await?
-  .map_err(|_| ApiError::err_plain("couldnt_mark_post_as_read").into())
+  .map_err(|e| ApiError::err("couldnt_mark_post_as_read", e).into())
+}
+
+pub async fn mark_post_as_unread(
+  person_id: PersonId,
+  post_id: PostId,
+  pool: &DbPool,
+) -> Result<usize, LemmyError> {
+  let post_read_form = PostReadForm { post_id, person_id };
+
+  blocking(pool, move |conn| {
+    PostRead::mark_as_unread(conn, &post_read_form)
+  })
+  .await?
+  .map_err(|e| ApiError::err("couldnt_mark_post_as_read", e).into())
 }
 
 pub async fn get_local_user_view_from_jwt(
index d4a8c3f521875e23e92d165151ca6bdadd36073a..6e2c3179734d2d001d1792cda5d31342758ae327 100644 (file)
@@ -92,6 +92,13 @@ pub struct RemovePost {
   pub auth: String,
 }
 
+#[derive(Serialize, Deserialize)]
+pub struct MarkPostAsRead {
+  pub post_id: PostId,
+  pub read: bool,
+  pub auth: String,
+}
+
 #[derive(Serialize, Deserialize)]
 pub struct LockPost {
   pub post_id: PostId,
index 2b1cba764969cc53588f79e86717ddf8581705fa..33954e6ec9461a4edc37c045f10f4d34ade9c80e 100644 (file)
@@ -1,6 +1,6 @@
 [package]
 name = "lemmy_api_crud"
-version = "0.14.1"
+version = "0.14.3"
 edition = "2018"
 description = "A link aggregator for the fediverse"
 license = "AGPL-3.0"
@@ -8,15 +8,15 @@ homepage = "https://join-lemmy.org/"
 documentation = "https://join-lemmy.org/docs/en/index.html"
 
 [dependencies]
-lemmy_apub = { version = "=0.14.1", path = "../apub" }
-lemmy_apub_lib = { version = "=0.14.1", path = "../apub_lib" }
-lemmy_utils = { version = "=0.14.1", path = "../utils" }
-lemmy_db_schema = { version = "=0.14.1", path = "../db_schema" }
-lemmy_db_views = { version = "=0.14.1", path = "../db_views" }
-lemmy_db_views_moderator = { version = "=0.14.1", path = "../db_views_moderator" }
-lemmy_db_views_actor = { version = "=0.14.1", path = "../db_views_actor" }
-lemmy_api_common = { version = "=0.14.1", path = "../api_common" }
-lemmy_websocket = { version = "=0.14.1", path = "../websocket" }
+lemmy_apub = { version = "=0.14.3", path = "../apub" }
+lemmy_apub_lib = { version = "=0.14.3", path = "../apub_lib" }
+lemmy_utils = { version = "=0.14.3", path = "../utils" }
+lemmy_db_schema = { version = "=0.14.3", path = "../db_schema" }
+lemmy_db_views = { version = "=0.14.3", path = "../db_views" }
+lemmy_db_views_moderator = { version = "=0.14.3", path = "../db_views_moderator" }
+lemmy_db_views_actor = { version = "=0.14.3", path = "../db_views_actor" }
+lemmy_api_common = { version = "=0.14.3", path = "../api_common" }
+lemmy_websocket = { version = "=0.14.3", path = "../websocket" }
 diesel = "1.4.8"
 bcrypt = "0.10.1"
 chrono = { version = "0.4.19", features = ["serde"] }
index 4cd42bb9b5720cd4c5da4741e1925d61c6fd2084..4789b84fe096a9a83381490273e06f957bbe52d0 100644 (file)
@@ -12,10 +12,39 @@ use lemmy_db_schema::{
   ListingType,
   SortType,
 };
-use lemmy_db_views::comment_view::CommentQueryBuilder;
+use lemmy_db_views::comment_view::{CommentQueryBuilder, CommentView};
 use lemmy_utils::{ApiError, ConnectionId, LemmyError};
 use lemmy_websocket::LemmyContext;
 
+#[async_trait::async_trait(?Send)]
+impl PerformCrud for GetComment {
+  type Response = CommentResponse;
+
+  async fn perform(
+    &self,
+    context: &Data<LemmyContext>,
+    _websocket_id: Option<ConnectionId>,
+  ) -> Result<Self::Response, LemmyError> {
+    let data = self;
+    let local_user_view =
+      get_local_user_view_from_jwt_opt(&data.auth, context.pool(), context.secret()).await?;
+
+    let person_id = local_user_view.map(|u| u.person.id);
+    let id = data.id;
+    let comment_view = blocking(context.pool(), move |conn| {
+      CommentView::read(conn, id, person_id)
+    })
+    .await?
+    .map_err(|e| ApiError::err("couldnt_find_comment", e))?;
+
+    Ok(Self::Response {
+      comment_view,
+      form_id: None,
+      recipient_ids: Vec::new(),
+    })
+  }
+}
+
 #[async_trait::async_trait(?Send)]
 impl PerformCrud for GetComments {
   type Response = GetCommentsResponse;
index f77632f908e97ee43406e95eae368ec4d10b1ec8..9f1553ee16b0edc4d006545de30eea8664dcce11 100644 (file)
@@ -108,6 +108,9 @@ pub async fn match_websocket_operation_crud(
     UserOperationCrud::RemoveComment => {
       do_websocket_operation::<RemoveComment>(context, id, op, data).await
     }
+    UserOperationCrud::GetComment => {
+      do_websocket_operation::<GetComment>(context, id, op, data).await
+    }
     UserOperationCrud::GetComments => {
       do_websocket_operation::<GetComments>(context, id, op, data).await
     }
index e7d49adbece02dfcf70228602252471fc29a4a6f..8a5b2edc4a8bc931a45211e5fd7d63aaed42a62f 100644 (file)
@@ -1,6 +1,6 @@
 [package]
 name = "lemmy_apub"
-version = "0.14.1"
+version = "0.14.3"
 edition = "2018"
 description = "A link aggregator for the fediverse"
 license = "AGPL-3.0"
@@ -13,13 +13,13 @@ path = "src/lib.rs"
 doctest = false
 
 [dependencies]
-lemmy_utils = { version = "=0.14.1", path = "../utils" }
-lemmy_apub_lib = { version = "=0.14.1", path = "../apub_lib" }
-lemmy_db_schema = { version = "=0.14.1", path = "../db_schema" }
-lemmy_db_views = { version = "=0.14.1", path = "../db_views" }
-lemmy_db_views_actor = { version = "=0.14.1", path = "../db_views_actor" }
-lemmy_api_common = { version = "=0.14.1", path = "../api_common" }
-lemmy_websocket = { version = "=0.14.1", path = "../websocket" }
+lemmy_utils = { version = "=0.14.3", path = "../utils" }
+lemmy_apub_lib = { version = "=0.14.3", path = "../apub_lib" }
+lemmy_db_schema = { version = "=0.14.3", path = "../db_schema" }
+lemmy_db_views = { version = "=0.14.3", path = "../db_views" }
+lemmy_db_views_actor = { version = "=0.14.3", path = "../db_views_actor" }
+lemmy_api_common = { version = "=0.14.3", path = "../api_common" }
+lemmy_websocket = { version = "=0.14.3", path = "../websocket" }
 diesel = "1.4.8"
 activitystreams-kinds = "0.1.2"
 bcrypt = "0.10.1"
index 0ab4b2b22e894f9109c83366533a7b39c879cccc..66ec3fc489563475a83d7ef53b9a546d670a2b30 100644 (file)
@@ -1,6 +1,6 @@
 [package]
 name = "lemmy_apub_lib"
-version = "0.14.1"
+version = "0.14.3"
 edition = "2018"
 description = "A link aggregator for the fediverse"
 license = "AGPL-3.0"
@@ -8,8 +8,8 @@ homepage = "https://join-lemmy.org/"
 documentation = "https://join-lemmy.org/docs/en/index.html"
 
 [dependencies]
-lemmy_utils = { version = "=0.14.1", path = "../utils" }
-lemmy_apub_lib_derive = { version = "=0.14.1", path = "../apub_lib_derive" }
+lemmy_utils = { version = "=0.14.3", path = "../utils" }
+lemmy_apub_lib_derive = { version = "=0.14.3", path = "../apub_lib_derive" }
 activitystreams = "0.7.0-alpha.11"
 serde = { version = "1.0.130", features = ["derive"] }
 async-trait = "0.1.51"
index f3b6e85f78f375629726edd5c81e81b227833b7c..176e47b90c804b152575118dc0b423b859911319 100644 (file)
@@ -1,6 +1,6 @@
 [package]
 name = "lemmy_apub_lib_derive"
-version = "0.14.1"
+version = "0.14.3"
 edition = "2018"
 description = "A link aggregator for the fediverse"
 license = "AGPL-3.0"
index f57228b6f92c92f40cf73a2c2fea33aac8ad416c..2cdf74b0141ef678cb077ef6e4a434d96b376545 100644 (file)
@@ -1,6 +1,6 @@
 [package]
 name = "lemmy_db_schema"
-version = "0.14.1"
+version = "0.14.3"
 edition = "2018"
 description = "A link aggregator for the fediverse"
 license = "AGPL-3.0"
@@ -11,8 +11,8 @@ documentation = "https://join-lemmy.org/docs/en/index.html"
 doctest = false
 
 [dependencies]
-lemmy_utils = { version = "=0.14.1", path = "../utils" }
-lemmy_apub_lib = { version = "=0.14.1", path = "../apub_lib" }
+lemmy_utils = { version = "=0.14.3", path = "../utils" }
+lemmy_apub_lib = { version = "=0.14.3", path = "../apub_lib" }
 diesel = { version = "1.4.8", features = ["postgres","chrono","r2d2","serde_json"] }
 diesel_migrations = "1.4.0"
 chrono = { version = "0.4.19", features = ["serde"] }
index 338b830212ebe76128dd7c0d28a4ee3c9fe041ca..c831bcd28ffd529ef6cb0c38b81045022f2e68a3 100644 (file)
@@ -1,6 +1,6 @@
 [package]
 name = "lemmy_db_views"
-version = "0.14.1"
+version = "0.14.3"
 edition = "2018"
 description = "A link aggregator for the fediverse"
 license = "AGPL-3.0"
@@ -11,7 +11,7 @@ documentation = "https://join-lemmy.org/docs/en/index.html"
 doctest = false
 
 [dependencies]
-lemmy_db_schema = { version = "=0.14.1", path = "../db_schema" }
+lemmy_db_schema = { version = "=0.14.3", path = "../db_schema" }
 diesel = { version = "1.4.8", features = ["postgres","chrono","r2d2","serde_json"] }
 serde = { version = "1.0.130", features = ["derive"] }
 tracing = "0.1.29"
index 5b39a5eb50f2c8dfbc3fa2bbe3bd46a5a777c57a..343851751251a233f64c4598b5bc6a3b4aa744a4 100644 (file)
@@ -147,22 +147,28 @@ impl CommentReportView {
     let mut query = comment_report::table
       .inner_join(comment::table)
       .inner_join(post::table.on(comment::post_id.eq(post::id)))
-      .inner_join(
-        community_moderator::table.on(community_moderator::community_id.eq(post::community_id)),
-      )
       .filter(comment_report::resolved.eq(false))
       .into_boxed();
 
-    // If its not an admin, get only the ones you mod
-    if !admin {
-      query = query.filter(community_moderator::person_id.eq(my_person_id));
-    }
-
     if let Some(community_id) = community_id {
       query = query.filter(post::community_id.eq(community_id))
     }
 
-    query.select(count(comment_report::id)).first::<i64>(conn)
+    // If its not an admin, get only the ones you mod
+    if !admin {
+      query
+        .inner_join(
+          community_moderator::table.on(
+            community_moderator::community_id
+              .eq(post::community_id)
+              .and(community_moderator::person_id.eq(my_person_id)),
+          ),
+        )
+        .select(count(comment_report::id))
+        .first::<i64>(conn)
+    } else {
+      query.select(count(comment_report::id)).first::<i64>(conn)
+    }
   }
 }
 
@@ -216,10 +222,6 @@ impl<'a> CommentReportQueryBuilder<'a> {
       .inner_join(community::table.on(post::community_id.eq(community::id)))
       .inner_join(person::table.on(comment_report::creator_id.eq(person::id)))
       .inner_join(person_alias_1::table.on(comment::creator_id.eq(person_alias_1::id)))
-      // Test this join
-      .inner_join(
-        community_moderator::table.on(community_moderator::community_id.eq(post::community_id)),
-      )
       .inner_join(
         comment_aggregates::table.on(comment_report::comment_id.eq(comment_aggregates::comment_id)),
       )
@@ -254,11 +256,6 @@ impl<'a> CommentReportQueryBuilder<'a> {
       ))
       .into_boxed();
 
-    // If its not an admin, get only the ones you mod
-    if !self.admin {
-      query = query.filter(community_moderator::person_id.eq(self.my_person_id));
-    }
-
     if let Some(community_id) = self.community_id {
       query = query.filter(post::community_id.eq(community_id));
     }
@@ -269,11 +266,25 @@ impl<'a> CommentReportQueryBuilder<'a> {
 
     let (limit, offset) = limit_and_offset(self.page, self.limit);
 
-    let res = query
-      .order_by(comment_report::published.asc())
+    query = query
+      .order_by(comment_report::published.desc())
       .limit(limit)
-      .offset(offset)
-      .load::<CommentReportViewTuple>(self.conn)?;
+      .offset(offset);
+
+    // If its not an admin, get only the ones you mod
+    let res = if !self.admin {
+      query
+        .inner_join(
+          community_moderator::table.on(
+            community_moderator::community_id
+              .eq(post::community_id)
+              .and(community_moderator::person_id.eq(self.my_person_id)),
+          ),
+        )
+        .load::<CommentReportViewTuple>(self.conn)?
+    } else {
+      query.load::<CommentReportViewTuple>(self.conn)?
+    };
 
     Ok(CommentReportView::from_tuple_to_vec(res))
   }
@@ -498,8 +509,8 @@ mod tests {
     assert_eq!(
       reports,
       [
-        expected_sara_report_view.to_owned(),
-        expected_jessica_report_view.to_owned()
+        expected_jessica_report_view.to_owned(),
+        expected_sara_report_view.to_owned()
       ]
     );
 
index f27ba50aad520c82f12d6b2878a515b4e40db4e2..e5594487c473d2686ee177cbfbceba7fba6b8a04 100644 (file)
@@ -131,23 +131,28 @@ impl PostReportView {
     use diesel::dsl::*;
     let mut query = post_report::table
       .inner_join(post::table)
-      // Test this join
-      .inner_join(
-        community_moderator::table.on(community_moderator::community_id.eq(post::community_id)),
-      )
       .filter(post_report::resolved.eq(false))
       .into_boxed();
 
-    // If its not an admin, get only the ones you mod
-    if !admin {
-      query = query.filter(community_moderator::person_id.eq(my_person_id));
-    }
-
     if let Some(community_id) = community_id {
       query = query.filter(post::community_id.eq(community_id))
     }
 
-    query.select(count(post_report::id)).first::<i64>(conn)
+    // If its not an admin, get only the ones you mod
+    if !admin {
+      query
+        .inner_join(
+          community_moderator::table.on(
+            community_moderator::community_id
+              .eq(post::community_id)
+              .and(community_moderator::person_id.eq(my_person_id)),
+          ),
+        )
+        .select(count(post_report::id))
+        .first::<i64>(conn)
+    } else {
+      query.select(count(post_report::id)).first::<i64>(conn)
+    }
   }
 }
 
@@ -200,9 +205,6 @@ impl<'a> PostReportQueryBuilder<'a> {
       .inner_join(community::table.on(post::community_id.eq(community::id)))
       .inner_join(person::table.on(post_report::creator_id.eq(person::id)))
       .inner_join(person_alias_1::table.on(post::creator_id.eq(person_alias_1::id)))
-      .inner_join(
-        community_moderator::table.on(community_moderator::community_id.eq(post::community_id)),
-      )
       .left_join(
         community_person_ban::table.on(
           post::community_id
@@ -234,11 +236,6 @@ impl<'a> PostReportQueryBuilder<'a> {
       ))
       .into_boxed();
 
-    // If its not an admin, get only the ones you mod
-    if !self.admin {
-      query = query.filter(community_moderator::person_id.eq(self.my_person_id));
-    }
-
     if let Some(community_id) = self.community_id {
       query = query.filter(post::community_id.eq(community_id));
     }
@@ -249,11 +246,25 @@ impl<'a> PostReportQueryBuilder<'a> {
 
     let (limit, offset) = limit_and_offset(self.page, self.limit);
 
-    let res = query
-      .order_by(post_report::published.asc())
+    query = query
+      .order_by(post_report::published.desc())
       .limit(limit)
-      .offset(offset)
-      .load::<PostReportViewTuple>(self.conn)?;
+      .offset(offset);
+
+    // If its not an admin, get only the ones you mod
+    let res = if !self.admin {
+      query
+        .inner_join(
+          community_moderator::table.on(
+            community_moderator::community_id
+              .eq(post::community_id)
+              .and(community_moderator::person_id.eq(self.my_person_id)),
+          ),
+        )
+        .load::<PostReportViewTuple>(self.conn)?
+    } else {
+      query.load::<PostReportViewTuple>(self.conn)?
+    };
 
     Ok(PostReportView::from_tuple_to_vec(res))
   }
@@ -481,8 +492,8 @@ mod tests {
     assert_eq!(
       reports,
       [
-        expected_sara_report_view.to_owned(),
-        expected_jessica_report_view.to_owned()
+        expected_jessica_report_view.to_owned(),
+        expected_sara_report_view.to_owned()
       ]
     );
 
index 8ba30a28c9da25b12b1d194fd7c6be701254c9a1..36a29081ca1d517bb7d7024ded9263ffd07fa0e4 100644 (file)
@@ -1,6 +1,6 @@
 [package]
 name = "lemmy_db_views_actor"
-version = "0.14.1"
+version = "0.14.3"
 edition = "2018"
 description = "A link aggregator for the fediverse"
 license = "AGPL-3.0"
@@ -11,6 +11,6 @@ documentation = "https://join-lemmy.org/docs/en/index.html"
 doctest = false
 
 [dependencies]
-lemmy_db_schema = { version = "=0.14.1", path = "../db_schema" }
+lemmy_db_schema = { version = "=0.14.3", path = "../db_schema" }
 diesel = { version = "1.4.8", features = ["postgres","chrono","r2d2","serde_json"] }
 serde = { version = "1.0.130", features = ["derive"] }
index 24cf6fee2c8950bfe04ce65b6aad18ed6ba8e2be..9128a955e8d4d4528920dd2511757a244c8e1c0b 100644 (file)
@@ -1,6 +1,6 @@
 [package]
 name = "lemmy_db_views_moderator"
-version = "0.14.1"
+version = "0.14.3"
 edition = "2018"
 description = "A link aggregator for the fediverse"
 license = "AGPL-3.0"
@@ -11,6 +11,6 @@ documentation = "https://join-lemmy.org/docs/en/index.html"
 doctest = false
 
 [dependencies]
-lemmy_db_schema = { version = "=0.14.1", path = "../db_schema" }
+lemmy_db_schema = { version = "=0.14.3", path = "../db_schema" }
 diesel = { version = "1.4.8", features = ["postgres","chrono","r2d2","serde_json"] }
 serde = { version = "1.0.130", features = ["derive"] }
index 357ae8a184b784ce4c104be9f497a08a1ff6225b..eee841846abd61fd3414470fe5027ed0bd6139df 100644 (file)
@@ -1,6 +1,6 @@
 [package]
 name = "lemmy_routes"
-version = "0.14.1"
+version = "0.14.3"
 edition = "2018"
 description = "A link aggregator for the fediverse"
 license = "AGPL-3.0"
@@ -11,13 +11,13 @@ documentation = "https://join-lemmy.org/docs/en/index.html"
 doctest = false
 
 [dependencies]
-lemmy_utils = { version = "=0.14.1", path = "../utils" }
-lemmy_websocket = { version = "=0.14.1", path = "../websocket" }
-lemmy_db_views = { version = "=0.14.1", path = "../db_views" }
-lemmy_db_views_actor = { version = "=0.14.1", path = "../db_views_actor" }
-lemmy_db_schema = { version = "=0.14.1", path = "../db_schema" }
-lemmy_api_common = { version = "=0.14.1", path = "../api_common" }
-lemmy_apub = { version = "=0.14.1", path = "../apub" }
+lemmy_utils = { version = "=0.14.3", path = "../utils" }
+lemmy_websocket = { version = "=0.14.3", path = "../websocket" }
+lemmy_db_views = { version = "=0.14.3", path = "../db_views" }
+lemmy_db_views_actor = { version = "=0.14.3", path = "../db_views_actor" }
+lemmy_db_schema = { version = "=0.14.3", path = "../db_schema" }
+lemmy_api_common = { version = "=0.14.3", path = "../api_common" }
+lemmy_apub = { version = "=0.14.3", path = "../apub" }
 diesel = "1.4.8"
 actix = "0.12.0"
 actix-web = { version = "4.0.0-beta.9", default-features = false, features = ["rustls"] }
index 02c6caddd164afd33def66a2929bb856a5c8671e..e30df04819f288557e7c6633cd2ee1fd62161ced 100644 (file)
@@ -1,6 +1,6 @@
 [package]
 name = "lemmy_utils"
-version = "0.14.1"
+version = "0.14.3"
 edition = "2018"
 description = "A link aggregator for the fediverse"
 license = "AGPL-3.0"
index 1f3252ffafe0727d26c6e2eb144c7161a1c65d14..1c33b4c5959af63331b3c207ea666c0073ea5a3a 100644 (file)
@@ -13,7 +13,7 @@ static MENTIONS_REGEX: Lazy<Regex> = Lazy::new(|| {
 static VALID_ACTOR_NAME_REGEX: Lazy<Regex> =
   Lazy::new(|| Regex::new(r"^[a-zA-Z0-9_]{3,}$").expect("compile regex"));
 static VALID_POST_TITLE_REGEX: Lazy<Regex> =
-  Lazy::new(|| Regex::new(r".*\S.*").expect("compile regex"));
+  Lazy::new(|| Regex::new(r".*\S{3,}.*").expect("compile regex"));
 static VALID_MATRIX_ID_REGEX: Lazy<Regex> = Lazy::new(|| {
   Regex::new(r"^@[A-Za-z0-9._=-]+:[A-Za-z0-9.-]+\.[A-Za-z]{2,}$").expect("compile regex")
 });
@@ -120,8 +120,14 @@ pub fn scrape_text_for_mentions(text: &str) -> Vec<MentionData> {
   out.into_iter().unique().collect()
 }
 
+fn has_newline(name: &str) -> bool {
+  name.contains('\n')
+}
+
 pub fn is_valid_actor_name(name: &str, actor_name_max_length: usize) -> bool {
-  name.chars().count() <= actor_name_max_length && VALID_ACTOR_NAME_REGEX.is_match(name)
+  name.chars().count() <= actor_name_max_length
+    && VALID_ACTOR_NAME_REGEX.is_match(name)
+    && !has_newline(name)
 }
 
 // Can't do a regex here, reverse lookarounds not supported
@@ -130,14 +136,15 @@ pub fn is_valid_display_name(name: &str, actor_name_max_length: usize) -> bool {
     && !name.starts_with('\u{200b}')
     && name.chars().count() >= 3
     && name.chars().count() <= actor_name_max_length
+    && !has_newline(name)
 }
 
 pub fn is_valid_matrix_id(matrix_id: &str) -> bool {
-  VALID_MATRIX_ID_REGEX.is_match(matrix_id)
+  VALID_MATRIX_ID_REGEX.is_match(matrix_id) && !has_newline(matrix_id)
 }
 
 pub fn is_valid_post_title(title: &str) -> bool {
-  VALID_POST_TITLE_REGEX.is_match(title)
+  VALID_POST_TITLE_REGEX.is_match(title) && !has_newline(title)
 }
 
 pub fn get_ip(conn_info: &ConnectionInfo) -> IpAddr {
@@ -166,7 +173,7 @@ pub fn clean_url_params(mut url: Url) -> Url {
 
 #[cfg(test)]
 mod tests {
-  use crate::utils::clean_url_params;
+  use crate::utils::{clean_url_params, is_valid_post_title};
   use url::Url;
 
   #[test]
@@ -180,4 +187,13 @@ mod tests {
     let cleaned = clean_url_params(url.clone());
     assert_eq!(url.to_string(), cleaned.to_string());
   }
+
+  #[test]
+  fn regex_checks() {
+    assert!(!is_valid_post_title("hi"));
+    assert!(is_valid_post_title("him"));
+    assert!(!is_valid_post_title("n\n\n\n\nanother"));
+    assert!(!is_valid_post_title("hello there!\n this is a test."));
+    assert!(is_valid_post_title("hello there! this is a test."));
+  }
 }
index 787faab1b641d212b0e8c5e17cfeaabba5c8bbde..6e9a7bf918ecebf02f66278ddf48d161efe88739 100644 (file)
@@ -1,6 +1,6 @@
 [package]
 name = "lemmy_websocket"
-version = "0.14.1"
+version = "0.14.3"
 edition = "2018"
 description = "A link aggregator for the fediverse"
 license = "AGPL-3.0"
@@ -13,11 +13,11 @@ path = "src/lib.rs"
 doctest = false
 
 [dependencies]
-lemmy_utils = { version = "=0.14.1", path = "../utils" }
-lemmy_api_common = { version = "=0.14.1", path = "../api_common" }
-lemmy_db_schema = { version = "=0.14.1", path = "../db_schema" }
-lemmy_db_views = { version = "=0.14.1", path = "../db_views" }
-lemmy_db_views_actor = { version = "=0.14.1", path = "../db_views_actor" }
+lemmy_utils = { version = "=0.14.3", path = "../utils" }
+lemmy_api_common = { version = "=0.14.3", path = "../api_common" }
+lemmy_db_schema = { version = "=0.14.3", path = "../db_schema" }
+lemmy_db_views = { version = "=0.14.3", path = "../db_views" }
+lemmy_db_views_actor = { version = "=0.14.3", path = "../db_views_actor" }
 reqwest = { version = "0.11.4", features = ["json"] }
 tracing = "0.1.29"
 rand = "0.8.4"
index 9fa258ff4fed6039e83b73295b2a998b4a9bd163..2b58b2c1effd03818ca54b1d5e6bc23a3eb24fd1 100644 (file)
@@ -491,7 +491,10 @@ impl ChatServer {
       } else {
         let user_operation = UserOperation::from_str(op)?;
         let fut = (message_handler)(context, msg.id, user_operation.clone(), data);
-        rate_limiter.message().wrap(ip, fut).await
+        match user_operation {
+          UserOperation::GetCaptcha => rate_limiter.post().wrap(ip, fut).await,
+          _ => rate_limiter.message().wrap(ip, fut).await,
+        }
       }
     }
   }
index b7ab5bf28b17680efb4f90b02094909361cabfc0..f422ac51ef3819f20cdb1e717918778993d00eab 100644 (file)
@@ -110,6 +110,7 @@ pub enum UserOperation {
   CreatePostLike,
   LockPost,
   StickyPost,
+  MarkPostAsRead,
   SavePost,
   CreatePostReport,
   ResolvePostReport,
@@ -168,6 +169,7 @@ pub enum UserOperationCrud {
   RemovePost,
   // Comment
   CreateComment,
+  GetComment,
   GetComments,
   EditComment,
   DeleteComment,
index 18a125e0d731b5ce0d48a652366147ed2b93a2ba..17fb3201bbe9ac7cef6a37b8a313bb14769bbadf 100644 (file)
@@ -26,7 +26,7 @@ services:
       - postgres
 
   lemmy-ui:
-    image: dessalines/lemmy-ui:0.14.1
+    image: dessalines/lemmy-ui:0.14.3
     restart: always
     environment:
       - LEMMY_INTERNAL_HOST=lemmy:8536
index cf01bc9b593d31dd95a39e16af30ffc0edca6d34..b33df80526482879ae04de5fc27ae91706e9dd3d 100644 (file)
@@ -28,7 +28,7 @@ services:
       - ./volumes/pictrs_alpha:/mnt
 
   lemmy-alpha-ui:
-    image: dessalines/lemmy-ui:0.14.1
+    image: dessalines/lemmy-ui:0.14.3
     environment:
       - LEMMY_INTERNAL_HOST=lemmy-alpha:8541
       - LEMMY_EXTERNAL_HOST=localhost:8541
@@ -57,7 +57,7 @@ services:
       - ./volumes/postgres_alpha:/var/lib/postgresql/data
 
   lemmy-beta-ui:
-    image: dessalines/lemmy-ui:0.14.1
+    image: dessalines/lemmy-ui:0.14.3
     environment:
       - LEMMY_INTERNAL_HOST=lemmy-beta:8551
       - LEMMY_EXTERNAL_HOST=localhost:8551
@@ -86,7 +86,7 @@ services:
       - ./volumes/postgres_beta:/var/lib/postgresql/data
 
   lemmy-gamma-ui:
-    image: dessalines/lemmy-ui:0.14.1
+    image: dessalines/lemmy-ui:0.14.3
     environment:
       - LEMMY_INTERNAL_HOST=lemmy-gamma:8561
       - LEMMY_EXTERNAL_HOST=localhost:8561
@@ -116,7 +116,7 @@ services:
 
   # An instance with only an allowlist for beta
   lemmy-delta-ui:
-    image: dessalines/lemmy-ui:0.14.1
+    image: dessalines/lemmy-ui:0.14.3
     environment:
       - LEMMY_INTERNAL_HOST=lemmy-delta:8571
       - LEMMY_EXTERNAL_HOST=localhost:8571
@@ -146,7 +146,7 @@ services:
 
   # An instance who has a blocklist, with lemmy-alpha blocked
   lemmy-epsilon-ui:
-    image: dessalines/lemmy-ui:0.14.1
+    image: dessalines/lemmy-ui:0.14.3
     environment:
       - LEMMY_INTERNAL_HOST=lemmy-epsilon:8581
       - LEMMY_EXTERNAL_HOST=localhost:8581
index eade097d12e2e0fa812115da496f20ab347f26c4..0c5969b818beb26f009ab71672220dcc18381c2d 100644 (file)
@@ -12,7 +12,7 @@ services:
     restart: always
 
   lemmy:
-    image: dessalines/lemmy:0.14.1
+    image: dessalines/lemmy:0.14.3
     ports:
       - "127.0.0.1:8536:8536"
     restart: always
@@ -25,7 +25,7 @@ services:
       - pictrs
 
   lemmy-ui:
-    image: dessalines/lemmy-ui:0.14.1
+    image: dessalines/lemmy-ui:0.14.3
     ports:
       - "127.0.0.1:1235:1234"
     restart: always
index fedd94f5e4182f1a62ed5482496c7b9997a983d3..84530508e94d3f131ddbbc23d98ca64f449cc93e 100644 (file)
@@ -6,13 +6,13 @@ delete from activity where ap_id is null;
 alter table activity alter column ap_id set not null;
 
 -- Delete dupes, keeping the first one
-delete
-from activity
-where id not in (
-  select min(id)
+delete from activity a using (
+  select min(id) as id, ap_id
   from activity
-  group by ap_id
-);
+  group by ap_id having count(*) > 1
+) b
+where a.ap_id = b.ap_id 
+and a.id <> b.id;
 
 -- The index
 create unique index idx_activity_ap_id on activity(ap_id);
diff --git a/migrations/2021-11-23-031528_add_report_published_index/down.sql b/migrations/2021-11-23-031528_add_report_published_index/down.sql
new file mode 100644 (file)
index 0000000..b5e9b51
--- /dev/null
@@ -0,0 +1,2 @@
+drop index idx_comment_report_published;
+drop index idx_post_report_published;
diff --git a/migrations/2021-11-23-031528_add_report_published_index/up.sql b/migrations/2021-11-23-031528_add_report_published_index/up.sql
new file mode 100644 (file)
index 0000000..eb0c122
--- /dev/null
@@ -0,0 +1,2 @@
+create index idx_comment_report_published on comment_report (published desc);
+create index idx_post_report_published on post_report (published desc);
index 0349f518c0253e7ca8a273c5adb1727c68736522..ae5fa40c18b12c4916b79bf9f8adb46f7bc440ef 100644 (file)
@@ -83,6 +83,10 @@ pub fn config(cfg: &mut web::ServiceConfig, rate_limit: &RateLimit) {
           .route("", web::put().to(route_post_crud::<EditPost>))
           .route("/delete", web::post().to(route_post_crud::<DeletePost>))
           .route("/remove", web::post().to(route_post_crud::<RemovePost>))
+          .route(
+            "/mark_as_read",
+            web::post().to(route_post::<MarkPostAsRead>),
+          )
           .route("/lock", web::post().to(route_post::<LockPost>))
           .route("/sticky", web::post().to(route_post::<StickyPost>))
           .route("/list", web::get().to(route_get_crud::<GetPosts>))
@@ -111,6 +115,7 @@ pub fn config(cfg: &mut web::ServiceConfig, rate_limit: &RateLimit) {
       .service(
         web::scope("/comment")
           .wrap(rate_limit.message())
+          .route("", web::get().to(route_get_crud::<GetComment>))
           .route("", web::put().to(route_post_crud::<EditComment>))
           .route("/delete", web::post().to(route_post_crud::<DeleteComment>))
           .route("/remove", web::post().to(route_post_crud::<RemoveComment>))
@@ -156,6 +161,12 @@ pub fn config(cfg: &mut web::ServiceConfig, rate_limit: &RateLimit) {
           .wrap(rate_limit.register())
           .route(web::post().to(route_post_crud::<Register>)),
       )
+      .service(
+        // Handle captcha separately
+        web::resource("/user/get_captcha")
+          .wrap(rate_limit.post())
+          .route(web::get().to(route_get::<GetCaptcha>)),
+      )
       // User actions
       .service(
         web::scope("/user")
@@ -173,7 +184,6 @@ pub fn config(cfg: &mut web::ServiceConfig, rate_limit: &RateLimit) {
           .route("/block", web::post().to(route_post::<BlockPerson>))
           // Account actions. I don't like that they're in /user maybe /accounts
           .route("/login", web::post().to(route_post::<Login>))
-          .route("/get_captcha", web::get().to(route_get::<GetCaptcha>))
           .route(
             "/delete_account",
             web::post().to(route_post_crud::<DeleteAccount>),