diff --git a/.gitignore b/.gitignore index 6ae0ae193..c3a8bd70e 100644 --- a/.gitignore +++ b/.gitignore @@ -16,5 +16,6 @@ ui/src/translations # ide config .idea/ +.vscode/ target diff --git a/docs/src/administration_backup_and_restore.md b/docs/src/administration_backup_and_restore.md index fe97cf880..633c687fb 100644 --- a/docs/src/administration_backup_and_restore.md +++ b/docs/src/administration_backup_and_restore.md @@ -9,14 +9,14 @@ When using docker or ansible, there should be a `volumes` folder, which contains To incrementally backup the DB to an `.sql` file, you can run: ```bash -docker exec -t FOLDERNAME_postgres_1 pg_dumpall -c -U lemmy > lemmy_dump_`date +%Y-%m-%d"_"%H_%M_%S`.sql +docker-compose exec postgres pg_dumpall -c -U lemmy > lemmy_dump_`date +%Y-%m-%d"_"%H_%M_%S`.sql ``` ### A Sample backup script ```bash #!/bin/sh # DB Backup -ssh MY_USER@MY_IP "docker exec -t FOLDERNAME_postgres_1 pg_dumpall -c -U lemmy" > ~/BACKUP_LOCATION/INSTANCE_NAME_dump_`date +%Y-%m-%d"_"%H_%M_%S`.sql +ssh MY_USER@MY_IP "docker-compose exec postgres pg_dumpall -c -U lemmy" > ~/BACKUP_LOCATION/INSTANCE_NAME_dump_`date +%Y-%m-%d"_"%H_%M_%S`.sql # Volumes folder Backup rsync -avP -zz --rsync-path="sudo rsync" MY_USER@MY_IP:/LEMMY_LOCATION/volumes ~/BACKUP_LOCATION/FOLDERNAME @@ -37,6 +37,45 @@ cat db_dump.sql | docker exec -i FOLDERNAME_postgres_1 psql -U lemmy # restore docker exec -i FOLDERNAME_postgres_1 psql -U lemmy -c "alter user lemmy with password 'bleh'" ``` +### Changing your domain name + +If you haven't federated yet, you can change your domain name in the DB. **Warning: do not do this after you've federated, or it will break federation.** + +Get into `psql` for your docker: + +`docker-compose exec postgres psql -U lemmy` + +``` +-- Post +update post set ap_id = replace (ap_id, 'old_domain', 'new_domain'); +update post set url = replace (url, 'old_domain', 'new_domain'); +update post set body = replace (body, 'old_domain', 'new_domain'); +update post set thumbnail_url = replace (thumbnail_url, 'old_domain', 'new_domain'); + +delete from post_aggregates_fast; +insert into post_aggregates_fast select * from post_aggregates_view; + +-- Comments +update comment set ap_id = replace (ap_id, 'old_domain', 'new_domain'); +update comment set content = replace (content, 'old_domain', 'new_domain'); + +delete from comment_aggregates_fast; +insert into comment_aggregates_fast select * from comment_aggregates_view; + +-- User +update user_ set actor_id = replace (actor_id, 'old_domain', 'new_domain'); +update user_ set avatar = replace (avatar, 'old_domain', 'new_domain'); + +delete from user_fast; +insert into user_fast select * from user_view; + +-- Community +update community set actor_id = replace (actor_id, 'old_domain', 'new_domain'); + +delete from community_aggregates_fast; +insert into community_aggregates_fast select * from community_aggregates_view; +``` + ## More resources - https://stackoverflow.com/questions/24718706/backup-restore-a-dockerized-postgresql-database diff --git a/server/Cargo.lock b/server/Cargo.lock index 3f19827be..eb29e4b1d 100644 --- a/server/Cargo.lock +++ b/server/Cargo.lock @@ -1,19 +1,10 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. [[package]] -name = "activitystreams-ext" -version = "0.1.0" -source = "git+https://yerbamate.dev/asonix/activitystreams-ext?branch=main#2799a4c606467a2f577e1f45f93c6828ec83cfdf" -dependencies = [ - "activitystreams-new", - "serde 1.0.114", - "serde_json", -] - -[[package]] -name = "activitystreams-new" -version = "0.1.0" -source = "git+https://yerbamate.dev/asonix/activitystreams-new?branch=main#857d5167dfa13054dd0d21d3d54f8147eea0d546" +name = "activitystreams" +version = "0.7.0-alpha.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3490e8e9d7744aada19fb2fb4e2564f8c22fd080a3561093ac91ed7d10bfe78" dependencies = [ "chrono", "mime", @@ -23,6 +14,17 @@ dependencies = [ "url", ] +[[package]] +name = "activitystreams-ext" +version = "0.1.0-alpha.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb8e19a0810cc25df3535061a08b7d8f8a734d309ea4411c57a9767e4a2ffa0e" +dependencies = [ + "activitystreams", + "serde 1.0.114", + "serde_json", +] + [[package]] name = "actix" version = "0.10.0-alpha.3" @@ -406,6 +408,12 @@ dependencies = [ "winapi 0.3.9", ] +[[package]] +name = "anyhow" +version = "1.0.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b602bfe940d21c130f3895acd65221e8a61270debe89d628b9cb4e3ccb8569b" + [[package]] name = "arc-swap" version = "0.4.7" @@ -1194,28 +1202,6 @@ dependencies = [ "termcolor", ] -[[package]] -name = "failure" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d32e9bd16cc02eae7db7ef620b392808b89f6a5e16bb3497d159c6b92a0f4f86" -dependencies = [ - "backtrace", - "failure_derive", -] - -[[package]] -name = "failure_derive" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa4da3c766cd7a0db8242e326e9e4e081edd567072893ed320008189715366a4" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "synstructure", -] - [[package]] name = "fake-simd" version = "0.1.2" @@ -1726,13 +1712,14 @@ dependencies = [ name = "lemmy_server" version = "0.0.1" dependencies = [ + "activitystreams", "activitystreams-ext", - "activitystreams-new", "actix", "actix-files", "actix-rt", "actix-web", "actix-web-actors", + "anyhow", "async-trait", "awc", "base64 0.12.3", @@ -1743,7 +1730,6 @@ dependencies = [ "diesel_migrations", "dotenv", "env_logger", - "failure", "futures", "http", "http-signature-normalization-actix", @@ -1762,6 +1748,7 @@ dependencies = [ "sha2", "strum", "strum_macros", + "thiserror", "tokio", "url", "uuid 0.8.1", @@ -3116,18 +3103,6 @@ dependencies = [ "unicode-xid", ] -[[package]] -name = "synstructure" -version = "0.12.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b834f2d66f734cb897113e34aaff2f1ab4719ca946f9a7358dba8f8064148701" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "unicode-xid", -] - [[package]] name = "tempfile" version = "3.1.0" diff --git a/server/Cargo.toml b/server/Cargo.toml index 3a652f298..dba0fee6f 100644 --- a/server/Cargo.toml +++ b/server/Cargo.toml @@ -18,12 +18,11 @@ lemmy_db = { path = "./lemmy_db" } diesel = "1.4.4" diesel_migrations = "1.4.0" dotenv = "0.15.0" -activitystreams-new = { git = "https://yerbamate.dev/asonix/activitystreams-new", branch = "main" } -activitystreams-ext = { git = "https://yerbamate.dev/asonix/activitystreams-ext", branch = "main" } +activitystreams = "0.7.0-alpha.3" +activitystreams-ext = "0.1.0-alpha.2" bcrypt = "0.8.0" chrono = { version = "0.4.7", features = ["serde"] } serde_json = { version = "1.0.52", features = ["preserve_order"]} -failure = "0.1.8" serde = { version = "1.0.105", features = ["derive"] } actix = "0.10.0-alpha.2" actix-web = { version = "3.0.0-alpha.3", features = ["rustls"] } @@ -52,3 +51,5 @@ uuid = { version = "0.8", features = ["serde", "v4"] } sha2 = "0.9" async-trait = "0.1.36" captcha = "0.0.7" +anyhow = "1.0.32" +thiserror = "1.0.20" diff --git a/server/src/api/mod.rs b/server/src/api/mod.rs index 901172601..11f958f08 100644 --- a/server/src/api/mod.rs +++ b/server/src/api/mod.rs @@ -9,6 +9,7 @@ use lemmy_db::{ user_view::*, Crud, }; +use thiserror::Error; pub mod claims; pub mod comment; @@ -17,8 +18,8 @@ pub mod post; pub mod site; pub mod user; -#[derive(Fail, Debug)] -#[fail(display = "{{\"error\":\"{}\"}}", message)] +#[derive(Debug, Error)] +#[error("{{\"error\":\"{message}\"}}")] pub struct APIError { pub message: String, } diff --git a/server/src/api/user.rs b/server/src/api/user.rs index c2b6955b5..f9a92cd39 100644 --- a/server/src/api/user.rs +++ b/server/src/api/user.rs @@ -97,6 +97,7 @@ pub struct SaveUserSettings { lang: String, avatar: Option, email: Option, + bio: Option, matrix_user_id: Option, new_password: Option, new_password_verify: Option, @@ -557,6 +558,17 @@ impl Perform for Oper { None => read_user.email, }; + let bio = match &data.bio { + Some(bio) => { + if bio.chars().count() <= 300 { + Some(bio.to_owned()) + } else { + return Err(APIError::err("bio_length_overflow").into()); + } + } + None => read_user.bio, + }; + let avatar = match &data.avatar { Some(avatar) => Some(avatar.to_owned()), None => read_user.avatar, @@ -613,7 +625,7 @@ impl Perform for Oper { show_avatars: data.show_avatars, send_notifications_to_email: data.send_notifications_to_email, actor_id: read_user.actor_id, - bio: read_user.bio, + bio, local: read_user.local, private_key: read_user.private_key, public_key: read_user.public_key, diff --git a/server/src/apub/activities.rs b/server/src/apub/activities.rs index a622c691d..9fdfe37fb 100644 --- a/server/src/apub/activities.rs +++ b/server/src/apub/activities.rs @@ -10,7 +10,7 @@ use crate::{ DbPool, LemmyError, }; -use activitystreams_new::base::AnyBase; +use activitystreams::base::AnyBase; use actix_web::client::Client; use lemmy_db::{community::Community, user::User_}; use lemmy_utils::{get_apub_protocol_string, settings::Settings}; diff --git a/server/src/apub/comment.rs b/server/src/apub/comment.rs index 650c60577..05b40dbe5 100644 --- a/server/src/apub/comment.rs +++ b/server/src/apub/comment.rs @@ -21,7 +21,7 @@ use crate::{ DbPool, LemmyError, }; -use activitystreams_new::{ +use activitystreams::{ activity::{ kind::{CreateType, DeleteType, DislikeType, LikeType, RemoveType, UndoType, UpdateType}, Create, diff --git a/server/src/apub/community.rs b/server/src/apub/community.rs index 584ef310c..96f0f84c3 100644 --- a/server/src/apub/community.rs +++ b/server/src/apub/community.rs @@ -18,8 +18,7 @@ use crate::{ DbPool, LemmyError, }; -use activitystreams_ext::Ext2; -use activitystreams_new::{ +use activitystreams::{ activity::{ kind::{AcceptType, AnnounceType, DeleteType, LikeType, RemoveType, UndoType}, Accept, @@ -37,6 +36,7 @@ use activitystreams_new::{ prelude::*, public, }; +use activitystreams_ext::Ext2; use actix_web::{body::Body, client::Client, web, HttpResponse}; use itertools::Itertools; use lemmy_db::{ @@ -403,7 +403,7 @@ pub async fn get_apub_community_followers( }) .await??; - let mut collection = UnorderedCollection::new(vec![]); + let mut collection = UnorderedCollection::new(); collection .set_context(context()) // TODO: this needs its own ID @@ -433,8 +433,9 @@ pub async fn get_apub_community_outbox( } let len = pages.len(); - let mut collection = OrderedCollection::new(pages); + let mut collection = OrderedCollection::new(); collection + .set_many_items(pages) .set_context(context()) .set_id(community.get_outbox_url()?) .set_total_items(len as u64); diff --git a/server/src/apub/extensions/group_extensions.rs b/server/src/apub/extensions/group_extensions.rs index 7dc42c4a0..3099a273e 100644 --- a/server/src/apub/extensions/group_extensions.rs +++ b/server/src/apub/extensions/group_extensions.rs @@ -1,6 +1,6 @@ use crate::LemmyError; +use activitystreams::unparsed::UnparsedMutExt; use activitystreams_ext::UnparsedExtension; -use activitystreams_new::unparsed::UnparsedMutExt; use diesel::PgConnection; use lemmy_db::{category::Category, Crud}; use serde::{Deserialize, Serialize}; diff --git a/server/src/apub/extensions/page_extension.rs b/server/src/apub/extensions/page_extension.rs index 3b0b89b5a..aa3d01604 100644 --- a/server/src/apub/extensions/page_extension.rs +++ b/server/src/apub/extensions/page_extension.rs @@ -1,5 +1,5 @@ +use activitystreams::unparsed::UnparsedMutExt; use activitystreams_ext::UnparsedExtension; -use activitystreams_new::unparsed::UnparsedMutExt; use serde::{Deserialize, Serialize}; #[derive(Clone, Debug, Default, Deserialize, Serialize)] diff --git a/server/src/apub/extensions/signatures.rs b/server/src/apub/extensions/signatures.rs index 5a1cdeb82..efc8dccfc 100644 --- a/server/src/apub/extensions/signatures.rs +++ b/server/src/apub/extensions/signatures.rs @@ -1,7 +1,8 @@ use crate::{apub::ActorType, LemmyError}; +use activitystreams::unparsed::UnparsedMutExt; use activitystreams_ext::UnparsedExtension; -use activitystreams_new::unparsed::UnparsedMutExt; use actix_web::{client::ClientRequest, HttpRequest}; +use anyhow::anyhow; use http_signature_normalization_actix::{ digest::{DigestClient, SignExt}, Config, @@ -70,7 +71,7 @@ pub fn verify(request: &HttpRequest, actor: &dyn ActorType) -> Result<(), LemmyE debug!("verified signature for {}", &request.uri()); Ok(()) } else { - Err(format_err!("Invalid signature on request: {}", &request.uri()).into()) + Err(anyhow!("Invalid signature on request: {}", &request.uri()).into()) } } diff --git a/server/src/apub/fetcher.rs b/server/src/apub/fetcher.rs index e2d505df7..4425757de 100644 --- a/server/src/apub/fetcher.rs +++ b/server/src/apub/fetcher.rs @@ -15,8 +15,9 @@ use crate::{ DbPool, LemmyError, }; -use activitystreams_new::{base::BaseExt, collection::OrderedCollection, object::Note, prelude::*}; +use activitystreams::{base::BaseExt, collection::OrderedCollection, object::Note, prelude::*}; use actix_web::client::Client; +use anyhow::anyhow; use chrono::NaiveDateTime; use diesel::{result::Error::NotFound, PgConnection}; use lemmy_db::{ @@ -66,7 +67,7 @@ where Response: for<'de> Deserialize<'de>, { if !is_apub_id_valid(&url) { - return Err(format_err!("Activitypub uri invalid or blocked: {}", url).into()); + return Err(anyhow!("Activitypub uri invalid or blocked: {}", url).into()); } let timeout = Duration::from_secs(60); @@ -125,10 +126,10 @@ pub async fn search_by_apub_id( let split2 = split[0].split('!').collect::>(); (format!("/c/{}", split2[1]), split[1]) } else { - return Err(format_err!("Invalid search query: {}", query).into()); + return Err(anyhow!("Invalid search query: {}", query).into()); } } else { - return Err(format_err!("Invalid search query: {}", query).into()); + return Err(anyhow!("Invalid search query: {}", query).into()); }; let url = format!("{}://{}{}", get_apub_protocol_string(), instance, name); @@ -348,7 +349,7 @@ async fn fetch_remote_community( // fetch outbox (maybe make this conditional) let outbox = fetch_remote_object::(client, &community.get_outbox_url()?).await?; - let outbox_items = outbox.items().clone(); + let outbox_items = outbox.items().unwrap().clone(); for o in outbox_items.many().unwrap() { let page = PageExt::from_any_base(o)?.unwrap(); let post = PostForm::from_apub(&page, client, pool).await?; diff --git a/server/src/apub/inbox/activities/announce.rs b/server/src/apub/inbox/activities/announce.rs index 78a005fb1..8ca4856fe 100644 --- a/server/src/apub/inbox/activities/announce.rs +++ b/server/src/apub/inbox/activities/announce.rs @@ -15,7 +15,7 @@ use crate::{ DbPool, LemmyError, }; -use activitystreams_new::{activity::*, base::AnyBase, prelude::ExtendsExt}; +use activitystreams::{activity::*, base::AnyBase, prelude::ExtendsExt}; use actix_web::{client::Client, HttpResponse}; pub async fn receive_announce( diff --git a/server/src/apub/inbox/activities/create.rs b/server/src/apub/inbox/activities/create.rs index 0f5595cd0..f8a92c1c6 100644 --- a/server/src/apub/inbox/activities/create.rs +++ b/server/src/apub/inbox/activities/create.rs @@ -21,7 +21,7 @@ use crate::{ DbPool, LemmyError, }; -use activitystreams_new::{activity::Create, base::AnyBase, object::Note, prelude::*}; +use activitystreams::{activity::Create, base::AnyBase, object::Note, prelude::*}; use actix_web::{client::Client, HttpResponse}; use lemmy_db::{ comment::{Comment, CommentForm}, diff --git a/server/src/apub/inbox/activities/delete.rs b/server/src/apub/inbox/activities/delete.rs index b4fe0de48..4fb56d321 100644 --- a/server/src/apub/inbox/activities/delete.rs +++ b/server/src/apub/inbox/activities/delete.rs @@ -20,7 +20,7 @@ use crate::{ DbPool, LemmyError, }; -use activitystreams_new::{activity::Delete, base::AnyBase, object::Note, prelude::*}; +use activitystreams::{activity::Delete, base::AnyBase, object::Note, prelude::*}; use actix_web::{client::Client, HttpResponse}; use lemmy_db::{ comment::{Comment, CommentForm}, diff --git a/server/src/apub/inbox/activities/dislike.rs b/server/src/apub/inbox/activities/dislike.rs index cb12724d6..1e67d1922 100644 --- a/server/src/apub/inbox/activities/dislike.rs +++ b/server/src/apub/inbox/activities/dislike.rs @@ -19,7 +19,7 @@ use crate::{ DbPool, LemmyError, }; -use activitystreams_new::{activity::Dislike, base::AnyBase, object::Note, prelude::*}; +use activitystreams::{activity::Dislike, base::AnyBase, object::Note, prelude::*}; use actix_web::{client::Client, HttpResponse}; use lemmy_db::{ comment::{CommentForm, CommentLike, CommentLikeForm}, diff --git a/server/src/apub/inbox/activities/like.rs b/server/src/apub/inbox/activities/like.rs index da92bbff3..9061773d0 100644 --- a/server/src/apub/inbox/activities/like.rs +++ b/server/src/apub/inbox/activities/like.rs @@ -19,7 +19,7 @@ use crate::{ DbPool, LemmyError, }; -use activitystreams_new::{activity::Like, base::AnyBase, object::Note, prelude::*}; +use activitystreams::{activity::Like, base::AnyBase, object::Note, prelude::*}; use actix_web::{client::Client, HttpResponse}; use lemmy_db::{ comment::{CommentForm, CommentLike, CommentLikeForm}, diff --git a/server/src/apub/inbox/activities/remove.rs b/server/src/apub/inbox/activities/remove.rs index af3d144b8..485d28616 100644 --- a/server/src/apub/inbox/activities/remove.rs +++ b/server/src/apub/inbox/activities/remove.rs @@ -20,7 +20,7 @@ use crate::{ DbPool, LemmyError, }; -use activitystreams_new::{activity::Remove, base::AnyBase, object::Note, prelude::*}; +use activitystreams::{activity::Remove, base::AnyBase, object::Note, prelude::*}; use actix_web::{client::Client, HttpResponse}; use lemmy_db::{ comment::{Comment, CommentForm}, diff --git a/server/src/apub/inbox/activities/undo.rs b/server/src/apub/inbox/activities/undo.rs index 332364843..edfcf372a 100644 --- a/server/src/apub/inbox/activities/undo.rs +++ b/server/src/apub/inbox/activities/undo.rs @@ -20,8 +20,9 @@ use crate::{ DbPool, LemmyError, }; -use activitystreams_new::{activity::*, base::AnyBase, object::Note, prelude::*}; +use activitystreams::{activity::*, base::AnyBase, object::Note, prelude::*}; use actix_web::{client::Client, HttpResponse}; +use anyhow::anyhow; use lemmy_db::{ comment::{Comment, CommentForm, CommentLike, CommentLikeForm}, comment_view::CommentView, @@ -63,7 +64,7 @@ async fn receive_undo_delete( "Note" => receive_undo_delete_comment(undo, &delete, client, pool, chat_server).await, "Page" => receive_undo_delete_post(undo, &delete, client, pool, chat_server).await, "Group" => receive_undo_delete_community(undo, &delete, client, pool, chat_server).await, - d => Err(format_err!("Undo Delete type {} not supported", d).into()), + d => Err(anyhow!("Undo Delete type {} not supported", d).into()), } } @@ -80,7 +81,7 @@ async fn receive_undo_remove( "Note" => receive_undo_remove_comment(undo, &remove, client, pool, chat_server).await, "Page" => receive_undo_remove_post(undo, &remove, client, pool, chat_server).await, "Group" => receive_undo_remove_community(undo, &remove, client, pool, chat_server).await, - d => Err(format_err!("Undo Delete type {} not supported", d).into()), + d => Err(anyhow!("Undo Delete type {} not supported", d).into()), } } @@ -96,7 +97,7 @@ async fn receive_undo_like( match type_ { "Note" => receive_undo_like_comment(undo, &like, client, pool, chat_server).await, "Page" => receive_undo_like_post(undo, &like, client, pool, chat_server).await, - d => Err(format_err!("Undo Delete type {} not supported", d).into()), + d => Err(anyhow!("Undo Delete type {} not supported", d).into()), } } @@ -109,7 +110,7 @@ async fn receive_undo_dislike( let dislike = Dislike::from_any_base(undo.object().to_owned().one().unwrap())?.unwrap(); let type_ = dislike.object().as_single_kind_str().unwrap(); - Err(format_err!("Undo Delete type {} not supported", type_).into()) + Err(anyhow!("Undo Delete type {} not supported", type_).into()) } async fn receive_undo_delete_comment( diff --git a/server/src/apub/inbox/activities/update.rs b/server/src/apub/inbox/activities/update.rs index 5da262e1f..9af1a2d38 100644 --- a/server/src/apub/inbox/activities/update.rs +++ b/server/src/apub/inbox/activities/update.rs @@ -22,7 +22,7 @@ use crate::{ DbPool, LemmyError, }; -use activitystreams_new::{activity::Update, base::AnyBase, object::Note, prelude::*}; +use activitystreams::{activity::Update, base::AnyBase, object::Note, prelude::*}; use actix_web::{client::Client, HttpResponse}; use lemmy_db::{ comment::{Comment, CommentForm}, diff --git a/server/src/apub/inbox/community_inbox.rs b/server/src/apub/inbox/community_inbox.rs index 8088ec5c3..69dd2cdf7 100644 --- a/server/src/apub/inbox/community_inbox.rs +++ b/server/src/apub/inbox/community_inbox.rs @@ -9,11 +9,12 @@ use crate::{ routes::{ChatServerParam, DbPoolParam}, LemmyError, }; -use activitystreams_new::{ +use activitystreams::{ activity::{Follow, Undo}, prelude::*, }; use actix_web::{client::Client, web, HttpRequest, HttpResponse}; +use anyhow::anyhow; use lemmy_db::{ community::{Community, CommunityFollower, CommunityFollowerForm}, user::User_, @@ -57,7 +58,7 @@ pub async fn community_inbox( if !community.local { return Err( - format_err!( + anyhow!( "Received activity is addressed to remote community {}", &community.actor_id ) diff --git a/server/src/apub/inbox/shared_inbox.rs b/server/src/apub/inbox/shared_inbox.rs index 3a2d1c43f..9e0cdb3d8 100644 --- a/server/src/apub/inbox/shared_inbox.rs +++ b/server/src/apub/inbox/shared_inbox.rs @@ -23,7 +23,7 @@ use crate::{ DbPool, LemmyError, }; -use activitystreams_new::{ +use activitystreams::{ activity::{ActorAndObject, ActorAndObjectRef}, base::{AsBase, Extends}, object::AsObject, diff --git a/server/src/apub/inbox/user_inbox.rs b/server/src/apub/inbox/user_inbox.rs index be99d81a0..b46f67027 100644 --- a/server/src/apub/inbox/user_inbox.rs +++ b/server/src/apub/inbox/user_inbox.rs @@ -12,7 +12,7 @@ use crate::{ DbPool, LemmyError, }; -use activitystreams_new::{ +use activitystreams::{ activity::{Accept, Create, Delete, Undo, Update}, object::Note, prelude::*, diff --git a/server/src/apub/mod.rs b/server/src/apub/mod.rs index feb1f30fc..e86032f61 100644 --- a/server/src/apub/mod.rs +++ b/server/src/apub/mod.rs @@ -20,16 +20,16 @@ use crate::{ DbPool, LemmyError, }; -use activitystreams_ext::{Ext1, Ext2}; -use activitystreams_new::{ +use activitystreams::{ activity::Follow, actor::{ApActor, Group, Person}, object::{Page, Tombstone}, prelude::*, }; +use activitystreams_ext::{Ext1, Ext2}; use actix_web::{body::Body, client::Client, HttpResponse}; +use anyhow::anyhow; use chrono::NaiveDateTime; -use failure::_core::fmt::Debug; use lemmy_db::{activity::do_insert_activity, user::User_}; use lemmy_utils::{convert_datetime, get_apub_protocol_string, settings::Settings, MentionData}; use log::debug; @@ -118,10 +118,10 @@ where tombstone.set_deleted(convert_datetime(updated)); Ok(tombstone) } else { - Err(format_err!("Cant convert to tombstone because updated time was None.").into()) + Err(anyhow!("Cant convert to tombstone because updated time was None.").into()) } } else { - Err(format_err!("Cant convert object to tombstone if it wasnt deleted").into()) + Err(anyhow!("Cant convert object to tombstone if it wasnt deleted").into()) } } @@ -339,13 +339,13 @@ pub async fn fetch_webfinger_url( .links .iter() .find(|l| l.type_.eq(&Some("application/activity+json".to_string()))) - .ok_or_else(|| format_err!("No application/activity+json link found."))?; + .ok_or_else(|| anyhow!("No application/activity+json link found."))?; link .href .to_owned() .map(|u| Url::parse(&u)) .transpose()? - .ok_or_else(|| format_err!("No href found.").into()) + .ok_or_else(|| anyhow!("No href found.").into()) } pub async fn insert_activity( @@ -355,7 +355,7 @@ pub async fn insert_activity( pool: &DbPool, ) -> Result<(), LemmyError> where - T: Serialize + Debug + Send + 'static, + T: Serialize + std::fmt::Debug + Send + 'static, { blocking(pool, move |conn| { do_insert_activity(conn, user_id, &data, local) diff --git a/server/src/apub/post.rs b/server/src/apub/post.rs index 39e4faf34..4b687b0ae 100644 --- a/server/src/apub/post.rs +++ b/server/src/apub/post.rs @@ -18,8 +18,7 @@ use crate::{ DbPool, LemmyError, }; -use activitystreams_ext::Ext1; -use activitystreams_new::{ +use activitystreams::{ activity::{ kind::{CreateType, DeleteType, DislikeType, LikeType, RemoveType, UndoType, UpdateType}, Create, @@ -35,6 +34,7 @@ use activitystreams_new::{ prelude::*, public, }; +use activitystreams_ext::Ext1; use actix_web::{body::Body, client::Client, web, HttpResponse}; use lemmy_db::{ community::Community, diff --git a/server/src/apub/private_message.rs b/server/src/apub/private_message.rs index f58a6bfed..69f552d3b 100644 --- a/server/src/apub/private_message.rs +++ b/server/src/apub/private_message.rs @@ -12,7 +12,7 @@ use crate::{ DbPool, LemmyError, }; -use activitystreams_new::{ +use activitystreams::{ activity::{ kind::{CreateType, DeleteType, UndoType, UpdateType}, Create, diff --git a/server/src/apub/user.rs b/server/src/apub/user.rs index 463208603..54e4552fd 100644 --- a/server/src/apub/user.rs +++ b/server/src/apub/user.rs @@ -13,8 +13,7 @@ use crate::{ DbPool, LemmyError, }; -use activitystreams_ext::Ext1; -use activitystreams_new::{ +use activitystreams::{ activity::{ kind::{FollowType, UndoType}, Follow, @@ -25,6 +24,7 @@ use activitystreams_new::{ object::{Image, Tombstone}, prelude::*, }; +use activitystreams_ext::Ext1; use actix_web::{body::Body, client::Client, web, HttpResponse}; use lemmy_db::{ naive_now, diff --git a/server/src/lib.rs b/server/src/lib.rs index 682efc774..ace843818 100644 --- a/server/src/lib.rs +++ b/server/src/lib.rs @@ -3,8 +3,6 @@ pub extern crate strum_macros; #[macro_use] pub extern crate lazy_static; -#[macro_use] -pub extern crate failure; pub extern crate actix; pub extern crate actix_web; pub extern crate base64; @@ -33,6 +31,7 @@ pub mod websocket; use crate::request::{retry, RecvError}; use actix_web::{client::Client, dev::ConnectionInfo}; +use anyhow::anyhow; use lemmy_utils::{get_apub_protocol_string, settings::Settings}; use log::error; use percent_encoding::{utf8_percent_encode, NON_ALPHANUMERIC}; @@ -48,12 +47,12 @@ pub type IPAddr = String; #[derive(Debug)] pub struct LemmyError { - inner: failure::Error, + inner: anyhow::Error, } impl From for LemmyError where - T: Into, + T: Into, { fn from(t: T) -> Self { LemmyError { inner: t.into() } @@ -118,7 +117,7 @@ pub async fn fetch_pictrs(client: &Client, image_url: &str) -> Result Result<(), Le if response .headers() .get("Content-Type") - .ok_or_else(|| format_err!("No Content-Type header"))? + .ok_or_else(|| anyhow!("No Content-Type header"))? .to_str()? .starts_with("image/") { Ok(()) } else { - Err(format_err!("Not an image type.").into()) + Err(anyhow!("Not an image type.").into()) } } diff --git a/server/src/request.rs b/server/src/request.rs index 7d09b60df..70a2b6933 100644 --- a/server/src/request.rs +++ b/server/src/request.rs @@ -1,12 +1,14 @@ use crate::LemmyError; +use anyhow::anyhow; use std::future::Future; +use thiserror::Error; -#[derive(Clone, Debug, Fail)] -#[fail(display = "Error sending request, {}", _0)] +#[derive(Clone, Debug, Error)] +#[error("Error sending request, {0}")] struct SendError(pub String); -#[derive(Clone, Debug, Fail)] -#[fail(display = "Error receiving response, {}", _0)] +#[derive(Clone, Debug, Error)] +#[error("Error receiving response, {0}")] pub struct RecvError(pub String); pub async fn retry(f: F) -> Result @@ -22,7 +24,7 @@ where F: Fn() -> Fut, Fut: Future, LemmyError>>, { - let mut response = Err(format_err!("connect timeout").into()); + let mut response = Err(anyhow!("connect timeout").into()); for _ in 0u8..3 { match (f)().await? { diff --git a/server/src/routes/feeds.rs b/server/src/routes/feeds.rs index 1322feb44..40e0ab658 100644 --- a/server/src/routes/feeds.rs +++ b/server/src/routes/feeds.rs @@ -1,5 +1,6 @@ use crate::{api::claims::Claims, blocking, routes::DbPoolParam, LemmyError}; use actix_web::{error::ErrorBadRequest, *}; +use anyhow::anyhow; use chrono::{DateTime, NaiveDateTime, Utc}; use diesel::{ r2d2::{ConnectionManager, Pool}, @@ -88,7 +89,7 @@ async fn get_feed( "c" => RequestType::Community, "front" => RequestType::Front, "inbox" => RequestType::Inbox, - _ => return Err(ErrorBadRequest(LemmyError::from(format_err!("wrong_type")))), + _ => return Err(ErrorBadRequest(LemmyError::from(anyhow!("wrong_type")))), }; let param = path.1.to_owned(); diff --git a/server/src/routes/nodeinfo.rs b/server/src/routes/nodeinfo.rs index 5094c2f15..a18d06ea2 100644 --- a/server/src/routes/nodeinfo.rs +++ b/server/src/routes/nodeinfo.rs @@ -1,5 +1,6 @@ use crate::{blocking, routes::DbPoolParam, version, LemmyError}; use actix_web::{body::Body, error::ErrorBadRequest, *}; +use anyhow::anyhow; use lemmy_db::site_view::SiteView; use lemmy_utils::{get_apub_protocol_string, settings::Settings}; use serde::{Deserialize, Serialize}; @@ -28,7 +29,7 @@ async fn node_info_well_known() -> Result, LemmyError> { async fn node_info(db: DbPoolParam) -> Result { let site_view = blocking(&db, SiteView::read) .await? - .map_err(|_| ErrorBadRequest(LemmyError::from(format_err!("not_found"))))?; + .map_err(|_| ErrorBadRequest(LemmyError::from(anyhow!("not_found"))))?; let protocols = if Settings::get().federation.enabled { vec!["activitypub".to_string()] diff --git a/server/src/routes/webfinger.rs b/server/src/routes/webfinger.rs index e616de0e8..81fad6110 100644 --- a/server/src/routes/webfinger.rs +++ b/server/src/routes/webfinger.rs @@ -1,5 +1,6 @@ use crate::{blocking, routes::DbPoolParam, LemmyError}; use actix_web::{error::ErrorBadRequest, web::Query, *}; +use anyhow::anyhow; use lemmy_db::{community::Community, user::User_}; use lemmy_utils::{settings::Settings, WEBFINGER_COMMUNITY_REGEX, WEBFINGER_USER_REGEX}; use serde::{Deserialize, Serialize}; @@ -62,17 +63,17 @@ async fn get_webfinger_response( Community::read_from_name(conn, &community_name) }) .await? - .map_err(|_| ErrorBadRequest(LemmyError::from(format_err!("not_found"))))? + .map_err(|_| ErrorBadRequest(LemmyError::from(anyhow!("not_found"))))? .actor_id } else if let Some(user_name) = user_regex_parsed { let user_name = user_name.as_str().to_owned(); // Make sure the requested user exists. blocking(&db, move |conn| User_::read_from_name(conn, &user_name)) .await? - .map_err(|_| ErrorBadRequest(LemmyError::from(format_err!("not_found"))))? + .map_err(|_| ErrorBadRequest(LemmyError::from(anyhow!("not_found"))))? .actor_id } else { - return Err(ErrorBadRequest(LemmyError::from(format_err!("not_found")))); + return Err(ErrorBadRequest(LemmyError::from(anyhow!("not_found")))); }; let json = WebFingerResponse { diff --git a/ui/package.json b/ui/package.json index f5ba9c8d4..aa803aa4a 100644 --- a/ui/package.json +++ b/ui/package.json @@ -33,7 +33,7 @@ "i18next": "^19.4.1", "inferno": "^7.4.2", "inferno-helmet": "^5.2.1", - "inferno-i18next": "nimbusec-oss/inferno-i18next", + "inferno-i18next": "github:nimbusec-oss/inferno-i18next#semver:^7.4.2", "inferno-router": "^7.4.2", "js-cookie": "^2.2.0", "jwt-decode": "^2.2.0", diff --git a/ui/src/components/markdown-textarea.tsx b/ui/src/components/markdown-textarea.tsx index 237ef9ff3..002d7c86b 100644 --- a/ui/src/components/markdown-textarea.tsx +++ b/ui/src/components/markdown-textarea.tsx @@ -21,6 +21,7 @@ interface MarkdownTextAreaProps { replyType?: boolean; focus?: boolean; disabled?: boolean; + maxLength?: number; onSubmit?(msg: { val: string; formId: string }): any; onContentChange?(val: string): any; onReplyCancel?(): any; @@ -121,7 +122,7 @@ export class MarkdownTextArea extends Component< required disabled={this.props.disabled} rows={2} - maxLength={10000} + maxLength={this.props.maxLength || 10000} /> {this.state.previewMode && (
{ show_avatars: null, send_notifications_to_email: null, auth: null, + bio: null, }, userSettingsLoading: null, deleteAccountLoading: null, @@ -149,7 +152,13 @@ export class User extends Component { this.handleUserSettingsListingTypeChange = this.handleUserSettingsListingTypeChange.bind( this ); + this.handleUserSettingsListingTypeChange = this.handleUserSettingsListingTypeChange.bind( + this + ); this.handlePageChange = this.handlePageChange.bind(this); + this.handleUserSettingsBioChange = this.handleUserSettingsBioChange.bind( + this + ); this.state.user_id = Number(this.props.match.params.id) || null; this.state.username = this.props.match.params.username; @@ -375,6 +384,12 @@ export class User extends Component { )} +
+
+
@@ -570,6 +585,18 @@ export class User extends Component { />
+
+ +
+ +
+