summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--docs/src/administration_configuration.md2
-rw-r--r--docs/src/contributing_websocket_http_api.md1
-rw-r--r--server/Cargo.lock4
-rw-r--r--server/Cargo.toml2
-rw-r--r--server/lemmy_db/src/comment_view.rs7
-rw-r--r--server/lemmy_db/src/community_view.rs2
-rw-r--r--server/lemmy_db/src/post_view.rs12
-rw-r--r--server/lemmy_db/src/schema.rs1
-rw-r--r--server/lemmy_db/src/user_mention_view.rs3
-rw-r--r--server/lemmy_db/src/user_view.rs5
-rw-r--r--server/lemmy_utils/src/lib.rs4
-rw-r--r--server/lemmy_utils/src/settings.rs11
-rw-r--r--server/migrations/2020-07-12-100442_add_post_title_to_comments_view/down.sql249
-rw-r--r--server/migrations/2020-07-12-100442_add_post_title_to_comments_view/up.sql254
-rw-r--r--server/src/api/post.rs11
-rw-r--r--server/src/routes/federation.rs22
-rw-r--r--ui/src/components/comment-node.tsx14
-rw-r--r--ui/src/components/inbox.tsx3
-rw-r--r--ui/src/components/user.tsx2
-rw-r--r--ui/src/interfaces.ts1
20 files changed, 594 insertions, 16 deletions
diff --git a/docs/src/administration_configuration.md b/docs/src/administration_configuration.md
index 56448de4..cc4c5689 100644
--- a/docs/src/administration_configuration.md
+++ b/docs/src/administration_configuration.md
@@ -5,6 +5,8 @@ The configuration is based on the file
This file also contains documentation for all the available options. To override the defaults, you
can copy the options you want to change into your local `config.hjson` file.
+To use a different `config.hjson` location than the current directory, set the environment variable `LEMMY_CONFIG_LOCATION`.
+
Additionally, you can override any config files with environment variables. These have the same
name as the config options, and are prefixed with `LEMMY_`. For example, you can override the
`database.password` with `LEMMY_DATABASE__POOL_SIZE=10`.
diff --git a/docs/src/contributing_websocket_http_api.md b/docs/src/contributing_websocket_http_api.md
index 567f674c..6ed25b98 100644
--- a/docs/src/contributing_websocket_http_api.md
+++ b/docs/src/contributing_websocket_http_api.md
@@ -1149,6 +1149,7 @@ Post listing types are `All, Subscribed, Community`
page: Option<i64>,
limit: Option<i64>,
community_id: Option<i32>,
+ community_name: Option<String>,
auth: Option<String>
}
}
diff --git a/server/Cargo.lock b/server/Cargo.lock
index 62438593..d90b9679 100644
--- a/server/Cargo.lock
+++ b/server/Cargo.lock
@@ -1422,9 +1422,9 @@ dependencies = [
[[package]]
name = "http-signature-normalization-actix"
-version = "0.4.0-alpha.0"
+version = "0.4.0-alpha.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "09afff6987c7edbed101d1cddd2185786fb0af0dd9c06b654aca73a0a763680f"
+checksum = "131fc982391a6b37847888b568cbe0e9cd302f1b0015f4f6f4a50234bebd049c"
dependencies = [
"actix-http",
"actix-web",
diff --git a/server/Cargo.toml b/server/Cargo.toml
index a5e5a583..2aa3c139 100644
--- a/server/Cargo.toml
+++ b/server/Cargo.toml
@@ -44,7 +44,7 @@ url = { version = "2.1.1", features = ["serde"] }
percent-encoding = "2.1.0"
openssl = "0.10"
http = "0.2.1"
-http-signature-normalization-actix = { version = "0.4.0-alpha.0", default-features = false, features = ["sha-2"] }
+http-signature-normalization-actix = { version = "0.4.0-alpha.2", default-features = false, features = ["sha-2"] }
base64 = "0.12.1"
tokio = "0.2.21"
futures = "0.3.5"
diff --git a/server/lemmy_db/src/comment_view.rs b/server/lemmy_db/src/comment_view.rs
index 914e568c..4af13c2d 100644
--- a/server/lemmy_db/src/comment_view.rs
+++ b/server/lemmy_db/src/comment_view.rs
@@ -9,6 +9,7 @@ table! {
id -> Int4,
creator_id -> Int4,
post_id -> Int4,
+ post_name -> Varchar,
parent_id -> Nullable<Int4>,
content -> Text,
removed -> Bool,
@@ -45,6 +46,7 @@ table! {
id -> Int4,
creator_id -> Int4,
post_id -> Int4,
+ post_name -> Varchar,
parent_id -> Nullable<Int4>,
content -> Text,
removed -> Bool,
@@ -84,6 +86,7 @@ pub struct CommentView {
pub id: i32,
pub creator_id: i32,
pub post_id: i32,
+ pub post_name: String,
pub parent_id: Option<i32>,
pub content: String,
pub removed: bool,
@@ -298,6 +301,7 @@ table! {
id -> Int4,
creator_id -> Int4,
post_id -> Int4,
+ post_name -> Varchar,
parent_id -> Nullable<Int4>,
content -> Text,
removed -> Bool,
@@ -338,6 +342,7 @@ pub struct ReplyView {
pub id: i32,
pub creator_id: i32,
pub post_id: i32,
+ pub post_name: String,
pub parent_id: Option<i32>,
pub content: String,
pub removed: bool,
@@ -576,6 +581,7 @@ mod tests {
content: "A test comment 32".into(),
creator_id: inserted_user.id,
post_id: inserted_post.id,
+ post_name: inserted_post.name.to_owned(),
community_id: inserted_community.id,
community_name: inserted_community.name.to_owned(),
parent_id: None,
@@ -610,6 +616,7 @@ mod tests {
content: "A test comment 32".into(),
creator_id: inserted_user.id,
post_id: inserted_post.id,
+ post_name: inserted_post.name.to_owned(),
community_id: inserted_community.id,
community_name: inserted_community.name.to_owned(),
parent_id: None,
diff --git a/server/lemmy_db/src/community_view.rs b/server/lemmy_db/src/community_view.rs
index b465ddab..5c6bd81a 100644
--- a/server/lemmy_db/src/community_view.rs
+++ b/server/lemmy_db/src/community_view.rs
@@ -299,6 +299,7 @@ impl CommunityModeratorView {
use super::community_view::community_moderator_view::dsl::*;
community_moderator_view
.filter(community_id.eq(from_community_id))
+ .order_by(published)
.load::<Self>(conn)
}
@@ -306,6 +307,7 @@ impl CommunityModeratorView {
use super::community_view::community_moderator_view::dsl::*;
community_moderator_view
.filter(user_id.eq(from_user_id))
+ .order_by(published)
.load::<Self>(conn)
}
}
diff --git a/server/lemmy_db/src/post_view.rs b/server/lemmy_db/src/post_view.rs
index b55359ea..3e9f8737 100644
--- a/server/lemmy_db/src/post_view.rs
+++ b/server/lemmy_db/src/post_view.rs
@@ -158,6 +158,7 @@ pub struct PostQueryBuilder<'a> {
my_user_id: Option<i32>,
for_creator_id: Option<i32>,
for_community_id: Option<i32>,
+ for_community_name: Option<String>,
search_term: Option<String>,
url_search: Option<String>,
show_nsfw: bool,
@@ -181,6 +182,7 @@ impl<'a> PostQueryBuilder<'a> {
my_user_id: None,
for_creator_id: None,
for_community_id: None,
+ for_community_name: None,
search_term: None,
url_search: None,
show_nsfw: true,
@@ -206,6 +208,11 @@ impl<'a> PostQueryBuilder<'a> {
self
}
+ pub fn for_community_name<T: MaybeOptional<String>>(mut self, for_community_name: T) -> Self {
+ self.for_community_name = for_community_name.get_optional();
+ self
+ }
+
pub fn for_creator_id<T: MaybeOptional<i32>>(mut self, for_creator_id: T) -> Self {
self.for_creator_id = for_creator_id.get_optional();
self
@@ -265,6 +272,11 @@ impl<'a> PostQueryBuilder<'a> {
query = query.then_order_by(stickied.desc());
}
+ if let Some(for_community_name) = self.for_community_name {
+ query = query.filter(community_name.eq(for_community_name));
+ query = query.then_order_by(stickied.desc());
+ }
+
if let Some(url_search) = self.url_search {
query = query.filter(url.eq(url_search));
}
diff --git a/server/lemmy_db/src/schema.rs b/server/lemmy_db/src/schema.rs
index 18a522df..9608fb7d 100644
--- a/server/lemmy_db/src/schema.rs
+++ b/server/lemmy_db/src/schema.rs
@@ -47,6 +47,7 @@ table! {
deleted -> Nullable<Bool>,
ap_id -> Nullable<Varchar>,
local -> Nullable<Bool>,
+ post_name -> Nullable<Varchar>,
community_id -> Nullable<Int4>,
community_actor_id -> Nullable<Varchar>,
community_local -> Nullable<Bool>,
diff --git a/server/lemmy_db/src/user_mention_view.rs b/server/lemmy_db/src/user_mention_view.rs
index 8bfbf453..359f166d 100644
--- a/server/lemmy_db/src/user_mention_view.rs
+++ b/server/lemmy_db/src/user_mention_view.rs
@@ -11,6 +11,7 @@ table! {
creator_actor_id -> Text,
creator_local -> Bool,
post_id -> Int4,
+ post_name -> Varchar,
parent_id -> Nullable<Int4>,
content -> Text,
removed -> Bool,
@@ -47,6 +48,7 @@ table! {
creator_actor_id -> Text,
creator_local -> Bool,
post_id -> Int4,
+ post_name -> Varchar,
parent_id -> Nullable<Int4>,
content -> Text,
removed -> Bool,
@@ -86,6 +88,7 @@ pub struct UserMentionView {
pub creator_actor_id: String,
pub creator_local: bool,
pub post_id: i32,
+ pub post_name: String,
pub parent_id: Option<i32>,
pub content: String,
pub removed: bool,
diff --git a/server/lemmy_db/src/user_view.rs b/server/lemmy_db/src/user_view.rs
index 84feba38..f2ac4742 100644
--- a/server/lemmy_db/src/user_view.rs
+++ b/server/lemmy_db/src/user_view.rs
@@ -157,7 +157,10 @@ impl UserView {
pub fn admins(conn: &PgConnection) -> Result<Vec<Self>, Error> {
use super::user_view::user_fast::dsl::*;
- user_fast.filter(admin.eq(true)).load::<Self>(conn)
+ user_fast
+ .filter(admin.eq(true))
+ .order_by(published)
+ .load::<Self>(conn)
}
pub fn banned(conn: &PgConnection) -> Result<Vec<Self>, Error> {
diff --git a/server/lemmy_utils/src/lib.rs b/server/lemmy_utils/src/lib.rs
index bbee8500..d88335e2 100644
--- a/server/lemmy_utils/src/lib.rs
+++ b/server/lemmy_utils/src/lib.rs
@@ -167,8 +167,8 @@ mod tests {
use crate::{
is_email_regex,
is_valid_community_name,
- is_valid_username,
is_valid_post_title,
+ is_valid_username,
remove_slurs,
scrape_text_for_mentions,
slur_check,
@@ -216,8 +216,6 @@ mod tests {
assert!(!is_valid_post_title("\n \n \n \n ")); // tabs/spaces/newlines
}
-
-
#[test]
fn test_slur_filter() {
let test =
diff --git a/server/lemmy_utils/src/settings.rs b/server/lemmy_utils/src/settings.rs
index 2ce33f58..0607974f 100644
--- a/server/lemmy_utils/src/settings.rs
+++ b/server/lemmy_utils/src/settings.rs
@@ -1,6 +1,7 @@
use config::{Config, ConfigError, Environment, File};
use serde::Deserialize;
use std::{fs, io::Error, net::IpAddr, sync::RwLock};
+use std::env;
static CONFIG_FILE_DEFAULTS: &str = "config/defaults.hjson";
static CONFIG_FILE: &str = "config/config.hjson";
@@ -83,7 +84,7 @@ impl Settings {
s.merge(File::with_name(CONFIG_FILE_DEFAULTS))?;
- s.merge(File::with_name(CONFIG_FILE).required(false))?;
+ s.merge(File::with_name(&Self::get_config_location()).required(false))?;
// Add in settings from the environment (with a prefix of LEMMY)
// Eg.. `LEMMY_DEBUG=1 ./target/app` would set the `debug` key
@@ -115,12 +116,16 @@ impl Settings {
format!("{}/api/v1", self.hostname)
}
+ pub fn get_config_location() -> String {
+ env::var("LEMMY_CONFIG_LOCATION").unwrap_or_else(|_| CONFIG_FILE.to_string())
+ }
+
pub fn read_config_file() -> Result<String, Error> {
- fs::read_to_string(CONFIG_FILE)
+ fs::read_to_string(Self::get_config_location())
}
pub fn save_config_file(data: &str) -> Result<String, Error> {
- fs::write(CONFIG_FILE, data)?;
+ fs::write(Self::get_config_location(), data)?;
// Reload the new settings
// From https://stackoverflow.com/questions/29654927/how-do-i-assign-a-string-to-a-mutable-static-variable/47181804#47181804
diff --git a/server/migrations/2020-07-12-100442_add_post_title_to_comments_view/down.sql b/server/migrations/2020-07-12-100442_add_post_title_to_comments_view/down.sql
new file mode 100644
index 00000000..b7c9d51e
--- /dev/null
+++ b/server/migrations/2020-07-12-100442_add_post_title_to_comments_view/down.sql
@@ -0,0 +1,249 @@
+drop view user_mention_view;
+drop view reply_fast_view;
+drop view comment_fast_view;
+drop view comment_view;
+
+drop view user_mention_fast_view;
+drop table comment_aggregates_fast;
+drop view comment_aggregates_view;
+
+create view comment_aggregates_view as
+select
+ ct.*,
+ -- community details
+ p.community_id,
+ c.actor_id as community_actor_id,
+ c."local" as community_local,
+ c."name" as community_name,
+ -- creator details
+ u.banned as banned,
+ coalesce(cb.id, 0)::bool as banned_from_community,
+ u.actor_id as creator_actor_id,
+ u.local as creator_local,
+ u.name as creator_name,
+ u.published as creator_published,
+ u.avatar as creator_avatar,
+ -- score details
+ coalesce(cl.total, 0) as score,
+ coalesce(cl.up, 0) as upvotes,
+ coalesce(cl.down, 0) as downvotes,
+ hot_rank(coalesce(cl.total, 0), ct.published) as hot_rank
+from comment ct
+left join post p on ct.post_id = p.id
+left join community c on p.community_id = c.id
+left join user_ u on ct.creator_id = u.id
+left join community_user_ban cb on ct.creator_id = cb.user_id and p.id = ct.post_id and p.community_id = cb.community_id
+left join (
+ select
+ l.comment_id as id,
+ sum(l.score) as total,
+ count(case when l.score = 1 then 1 else null end) as up,
+ count(case when l.score = -1 then 1 else null end) as down
+ from comment_like l
+ group by comment_id
+) as cl on cl.id = ct.id;
+
+create or replace view comment_view as (
+select
+ cav.*,
+ us.user_id as user_id,
+ us.my_vote as my_vote,
+ us.is_subbed::bool as subscribed,
+ us.is_saved::bool as saved
+from comment_aggregates_view cav
+cross join lateral (
+ select
+ u.id as user_id,
+ coalesce(cl.score, 0) as my_vote,
+ coalesce(cf.id, 0) as is_subbed,
+ coalesce(cs.id, 0) as is_saved
+ from user_ u
+ left join comment_like cl on u.id = cl.user_id and cav.id = cl.comment_id
+ left join comment_saved cs on u.id = cs.user_id and cs.comment_id = cav.id
+ left join community_follower cf on u.id = cf.user_id and cav.community_id = cf.community_id
+) as us
+
+union all
+
+select
+ cav.*,
+ null as user_id,
+ null as my_vote,
+ null as subscribed,
+ null as saved
+from comment_aggregates_view cav
+);
+
+create table comment_aggregates_fast as select * from comment_aggregates_view;
+alter table comment_aggregates_fast add primary key (id);
+
+create view comment_fast_view as
+select
+ cav.*,
+ us.user_id as user_id,
+ us.my_vote as my_vote,
+ us.is_subbed::bool as subscribed,
+ us.is_saved::bool as saved
+from comment_aggregates_fast cav
+cross join lateral (
+ select
+ u.id as user_id,
+ coalesce(cl.score, 0) as my_vote,
+ coalesce(cf.id, 0) as is_subbed,
+ coalesce(cs.id, 0) as is_saved
+ from user_ u
+ left join comment_like cl on u.id = cl.user_id and cav.id = cl.comment_id
+ left join comment_saved cs on u.id = cs.user_id and cs.comment_id = cav.id
+ left join community_follower cf on u.id = cf.user_id and cav.community_id = cf.community_id
+) as us
+
+union all
+
+select
+ cav.*,
+ null as user_id,
+ null as my_vote,
+ null as subscribed,
+ null as saved
+from comment_aggregates_fast cav;
+
+create view user_mention_view as
+select
+ c.id,
+ um.id as user_mention_id,
+ c.creator_id,
+ c.creator_actor_id,
+ c.creator_local,
+ c.post_id,
+ c.parent_id,
+ c.content,
+ c.removed,
+ um.read,
+ c.published,
+ c.updated,
+ c.deleted,
+ c.community_id,
+ c.community_actor_id,
+ c.community_local,
+ c.community_name,
+ c.banned,
+ c.banned_from_community,
+ c.creator_name,
+ c.creator_avatar,
+ c.score,
+ c.upvotes,
+ c.downvotes,
+ c.hot_rank,
+ c.user_id,
+ c.my_vote,
+ c.saved,
+ um.recipient_id,
+ (select actor_id from user_ u where u.id = um.recipient_id) as recipient_actor_id,
+ (select local from user_ u where u.id = um.recipient_id) as recipient_local
+from user_mention um, comment_view c
+where um.comment_id = c.id;
+
+create view user_mention_fast_view as
+select
+ ac.id,
+ um.id as user_mention_id,
+ ac.creator_id,
+ ac.creator_actor_id,
+ ac.creator_local,
+ ac.post_id,
+ ac.parent_id,
+ ac.content,
+ ac.removed,
+ um.read,
+ ac.published,
+ ac.updated,
+ ac.deleted,
+ ac.community_id,
+ ac.community_actor_id,
+ ac.community_local,
+ ac.community_name,
+ ac.banned,
+ ac.banned_from_community,
+ ac.creator_name,
+ ac.creator_avatar,
+ ac.score,
+ ac.upvotes,
+ ac.downvotes,
+ ac.hot_rank,
+ u.id as user_id,
+ coalesce(cl.score, 0) as my_vote,
+ (select cs.id::bool from comment_saved cs where u.id = cs.user_id and cs.comment_id = ac.id) as saved,
+ um.recipient_id,
+ (select actor_id from user_ u where u.id = um.recipient_id) as recipient_actor_id,
+ (select local from user_ u where u.id = um.recipient_id) as recipient_local
+from user_ u
+cross join (
+ select
+ ca.*
+ from comment_aggregates_fast ca
+) ac
+left join comment_like cl on u.id = cl.user_id and ac.id = cl.comment_id
+left join user_mention um on um.comment_id = ac.id
+
+union all
+
+select
+ ac.id,
+ um.id as user_mention_id,
+ ac.creator_id,
+ ac.creator_actor_id,
+ ac.creator_local,
+ ac.post_id,
+ ac.parent_id,
+ ac.content,
+ ac.removed,
+ um.read,
+ ac.published,
+ ac.updated,
+ ac.deleted,
+ ac.community_id,
+ ac.community_actor_id,
+ ac.community_local,
+ ac.community_name,
+ ac.banned,
+ ac.banned_from_community,
+ ac.creator_name,
+ ac.creator_avatar,
+ ac.score,
+ ac.upvotes,
+ ac.downvotes,
+ ac.hot_rank,
+ null as user_id,
+ null as my_vote,
+ null as saved,
+ um.recipient_id,
+ (select actor_id from user_ u where u.id = um.recipient_id) as recipient_actor_id,
+ (select local from user_ u where u.id = um.recipient_id) as recipient_local
+from comment_aggregates_fast ac
+left join user_mention um on um.comment_id = ac.id
+;
+
+-- Do the reply_view referencing the comment_fast_view
+create view reply_fast_view as
+with closereply as (
+ select
+ c2.id,
+ c2.creator_id as sender_id,
+ c.creator_id as recipient_id
+ from comment c
+ inner join comment c2 on c.id = c2.parent_id
+ where c2.creator_id != c.creator_id
+ -- Do union where post is null
+ union
+ select
+ c.id,
+ c.creator_id as sender_id,
+ p.creator_id as recipient_id
+ from comment c, post p
+ where c.post_id = p.id and c.parent_id is null and c.creator_id != p.creator_id
+)
+select cv.*,
+closereply.recipient_id
+from comment_fast_view cv, closereply
+where closereply.id = cv.id
+; \ No newline at end of file
diff --git a/server/migrations/2020-07-12-100442_add_post_title_to_comments_view/up.sql b/server/migrations/2020-07-12-100442_add_post_title_to_comments_view/up.sql
new file mode 100644
index 00000000..4cfa7edb
--- /dev/null
+++ b/server/migrations/2020-07-12-100442_add_post_title_to_comments_view/up.sql
@@ -0,0 +1,254 @@
+drop view user_mention_view;
+drop view reply_fast_view;
+drop view comment_fast_view;
+drop view comment_view;
+
+drop view user_mention_fast_view;
+drop table comment_aggregates_fast;
+drop view comment_aggregates_view;
+
+create view comment_aggregates_view as
+select
+ ct.*,
+ -- post details
+ p."name" as post_name,
+ p.community_id,
+ -- community details
+ c.actor_id as community_actor_id,
+ c."local" as community_local,
+ c."name" as community_name,
+ -- creator details
+ u.banned as banned,
+ coalesce(cb.id, 0)::bool as banned_from_community,
+ u.actor_id as creator_actor_id,
+ u.local as creator_local,
+ u.name as creator_name,
+ u.published as creator_published,
+ u.avatar as creator_avatar,
+ -- score details
+ coalesce(cl.total, 0) as score,
+ coalesce(cl.up, 0) as upvotes,
+ coalesce(cl.down, 0) as downvotes,
+ hot_rank(coalesce(cl.total, 0), ct.published) as hot_rank
+from comment ct
+left join post p on ct.post_id = p.id
+left join community c on p.community_id = c.id
+left join user_ u on ct.creator_id = u.id
+left join community_user_ban cb on ct.creator_id = cb.user_id and p.id = ct.post_id and p.community_id = cb.community_id
+left join (
+ select
+ l.comment_id as id,
+ sum(l.score) as total,
+ count(case when l.score = 1 then 1 else null end) as up,
+ count(case when l.score = -1 then 1 else null end) as down
+ from comment_like l
+ group by comment_id
+) as cl on cl.id = ct.id;
+
+create or replace view comment_view as (
+select
+ cav.*,
+ us.user_id as user_id,
+ us.my_vote as my_vote,
+ us.is_subbed::bool as subscribed,
+ us.is_saved::bool as saved
+from comment_aggregates_view cav
+cross join lateral (
+ select
+ u.id as user_id,
+ coalesce(cl.score, 0) as my_vote,
+ coalesce(cf.id, 0) as is_subbed,
+ coalesce(cs.id, 0) as is_saved
+ from user_ u
+ left join comment_like cl on u.id = cl.user_id and cav.id = cl.comment_id
+ left join comment_saved cs on u.id = cs.user_id and cs.comment_id = cav.id
+ left join community_follower cf on u.id = cf.user_id and cav.community_id = cf.community_id
+) as us
+
+union all
+
+select
+ cav.*,
+ null as user_id,
+ null as my_vote,
+ null as subscribed,
+ null as saved
+from comment_aggregates_view cav
+);
+
+create table comment_aggregates_fast as select * from comment_aggregates_view;
+alter table comment_aggregates_fast add primary key (id);
+
+create view comment_fast_view as
+select
+ cav.*,
+ us.user_id as user_id,
+ us.my_vote as my_vote,
+ us.is_subbed::bool as subscribed,
+ us.is_saved::bool as saved
+from comment_aggregates_fast cav
+cross join lateral (
+ select
+ u.id as user_id,
+ coalesce(cl.score, 0) as my_vote,
+ coalesce(cf.id, 0) as is_subbed,
+ coalesce(cs.id, 0) as is_saved
+ from user_ u
+ left join comment_like cl on u.id = cl.user_id and cav.id = cl.comment_id
+ left join comment_saved cs on u.id = cs.user_id and cs.comment_id = cav.id
+ left join community_follower cf on u.id = cf.user_id and cav.community_id = cf.community_id
+) as us
+
+union all
+
+select
+ cav.*,
+ null as user_id,
+ null as my_vote,
+ null as subscribed,
+ null as saved
+from comment_aggregates_fast cav;
+
+create view user_mention_view as
+select
+ c.id,
+ um.id as user_mention_id,
+ c.creator_id,
+ c.creator_actor_id,
+ c.creator_local,
+ c.post_id,
+ c.post_name,
+ c.parent_id,
+ c.content,
+ c.removed,
+ um.read,
+ c.published,
+ c.updated,
+ c.deleted,
+ c.community_id,
+ c.community_actor_id,
+ c.community_local,
+ c.community_name,
+ c.banned,
+ c.banned_from_community,
+ c.creator_name,
+ c.creator_avatar,
+ c.score,
+ c.upvotes,
+ c.downvotes,
+ c.hot_rank,
+ c.user_id,
+ c.my_vote,
+ c.saved,
+ um.recipient_id,
+ (select actor_id from user_ u where u.id = um.recipient_id) as recipient_actor_id,
+ (select local from user_ u where u.id = um.recipient_id) as recipient_local
+from user_mention um, comment_view c
+where um.comment_id = c.id;
+
+create view user_mention_fast_view as
+select
+ ac.id,
+ um.id as user_mention_id,
+ ac.creator_id,
+ ac.creator_actor_id,
+ ac.creator_local,
+ ac.post_id,
+ ac.post_name,
+ ac.parent_id,
+ ac.content,
+ ac.removed,
+ um.read,
+ ac.published,
+ ac.updated,
+ ac.deleted,
+ ac.community_id,
+ ac.community_actor_id,
+ ac.community_local,
+ ac.community_name,
+ ac.banned,
+ ac.banned_from_community,
+ ac.creator_name,
+ ac.creator_avatar,
+ ac.score,
+ ac.upvotes,
+ ac.downvotes,
+ ac.hot_rank,
+ u.id as user_id,
+ coalesce(cl.score, 0) as my_vote,
+ (select cs.id::bool from comment_saved cs where u.id = cs.user_id and cs.comment_id = ac.id) as saved,
+ um.recipient_id,
+ (select actor_id from user_ u where u.id = um.recipient_id) as recipient_actor_id,
+ (select local from user_ u where u.id = um.recipient_id) as recipient_local
+from user_ u
+cross join (
+ select
+ ca.*
+ from comment_aggregates_fast ca
+) ac
+left join comment_like cl on u.id = cl.user_id and ac.id = cl.comment_id
+left join user_mention um on um.comment_id = ac.id
+
+union all
+
+select
+ ac.id,
+ um.id as user_mention_id,
+ ac.creator_id,
+ ac.creator_actor_id,
+ ac.creator_local,
+ ac.post_id,
+ ac.post_name,
+ ac.parent_id,
+ ac.content,
+ ac.removed,
+ um.read,
+ ac.published,
+ ac.updated,
+ ac.deleted,
+ ac.community_id,
+ ac.community_actor_id,
+ ac.community_local,
+ ac.community_name,
+ ac.banned,
+ ac.banned_from_community,
+ ac.creator_name,
+ ac.creator_avatar,
+ ac.score,
+ ac.upvotes,
+ ac.downvotes,
+ ac.hot_rank,
+ null as user_id,
+ null as my_vote,
+ null as saved,
+ um.recipient_id,
+ (select actor_id from user_ u where u.id = um.recipient_id) as recipient_actor_id,
+ (select local from user_ u where u.id = um.recipient_id) as recipient_local
+from comment_aggregates_fast ac
+left join user_mention um on um.comment_id = ac.id
+;
+
+-- Do the reply_view referencing the comment_fast_view
+create view reply_fast_view as
+with closereply as (
+ select
+ c2.id,
+ c2.creator_id as sender_id,
+ c.creator_id as recipient_id
+ from comment c
+ inner join comment c2 on c.id = c2.parent_id
+ where c2.creator_id != c.creator_id
+ -- Do union where post is null
+ union
+ select
+ c.id,
+ c.creator_id as sender_id,
+ p.creator_id as recipient_id
+ from comment c, post p
+ where c.post_id = p.id and c.parent_id is null and c.creator_id != p.creator_id
+)
+select cv.*,
+closereply.recipient_id
+from comment_fast_view cv, closereply
+where closereply.id = cv.id
+; \ No newline at end of file
diff --git a/server/src/api/post.rs b/server/src/api/post.rs
index cbdb976c..6710a2cd 100644
--- a/server/src/api/post.rs
+++ b/server/src/api/post.rs
@@ -28,7 +28,13 @@ use lemmy_db::{
Saveable,
SortType,
};
-use lemmy_utils::{is_valid_post_title, make_apub_endpoint, slur_check, slurs_vec_to_str, EndpointType};
+use lemmy_utils::{
+ is_valid_post_title,
+ make_apub_endpoint,
+ slur_check,
+ slurs_vec_to_str,
+ EndpointType,
+};
use serde::{Deserialize, Serialize};
use std::str::FromStr;
@@ -70,6 +76,7 @@ pub struct GetPosts {
page: Option<i64>,
limit: Option<i64>,
pub community_id: Option<i32>,
+ pub community_name: Option<String>,
auth: Option<String>,
}
@@ -369,12 +376,14 @@ impl Perform for Oper<GetPosts> {
let page = data.page;
let limit = data.limit;
let community_id = data.community_id;
+ let community_name = data.community_name.to_owned();
let posts = match blocking(pool, move |conn| {
PostQueryBuilder::create(conn)
.listing_type(type_)
.sort(&sort)
.show_nsfw(show_nsfw)
.for_community_id(community_id)
+ .for_community_name(community_name)
.my_user_id(user_id)
.page(page)
.limit(limit)
diff --git a/server/src/routes/federation.rs b/server/src/routes/federation.rs
index ebab139a..cd4c4780 100644
--- a/server/src/routes/federation.rs
+++ b/server/src/routes/federation.rs
@@ -9,11 +9,15 @@ use crate::apub::{
APUB_JSON_CONTENT_TYPE,
};
use actix_web::*;
+use http_signature_normalization_actix::digest::middleware::VerifyDigest;
use lemmy_utils::settings::Settings;
+use sha2::{Digest, Sha256};
pub fn config(cfg: &mut web::ServiceConfig) {
if Settings::get().federation.enabled {
println!("federation enabled, host is {}", Settings::get().hostname);
+ let digest_verifier = VerifyDigest::new(Sha256::new());
+
cfg
.service(
web::scope("/")
@@ -36,8 +40,20 @@ pub fn config(cfg: &mut web::ServiceConfig) {
.route("/comment/{comment_id}", web::get().to(get_apub_comment)),
)
// Inboxes dont work with the header guard for some reason.
- .route("/c/{community_name}/inbox", web::post().to(community_inbox))
- .route("/u/{user_name}/inbox", web::post().to(user_inbox))
- .route("/inbox", web::post().to(shared_inbox));
+ .service(
+ web::resource("/c/{community_name}/inbox")
+ .wrap(digest_verifier.clone())
+ .route(web::post().to(community_inbox)),
+ )
+ .service(
+ web::resource("/u/{user_name}/inbox")
+ .wrap(digest_verifier.clone())
+ .route(web::post().to(user_inbox)),
+ )
+ .service(
+ web::resource("/inbox")
+ .wrap(digest_verifier)
+ .route(web::post().to(shared_inbox)),
+ );
}
}
diff --git a/ui/src/components/comment-node.tsx b/ui/src/components/comment-node.tsx
index 82af0bbe..a6b9b7ba 100644
--- a/ui/src/components/comment-node.tsx
+++ b/ui/src/components/comment-node.tsx
@@ -32,6 +32,7 @@ import { MomentTime } from './moment-time';
import { CommentForm } from './comment-form';
import { CommentNodes } from './comment-nodes';
import { UserListing } from './user-listing';
+import { CommunityLink } from './community-link';
import { i18n } from '../i18next';
interface CommentNodeState {
@@ -186,8 +187,17 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
{this.props.showCommunity && (
<>
<span class="mx-1">{i18n.t('to')}</span><