mirror of
https://github.com/LemmyNet/lemmy.git
synced 2024-09-09 16:08:49 -06:00
Merge remote-tracking branch 'origin/main' into persistent-queue
This commit is contained in:
commit
b526727a55
@ -10,9 +10,9 @@ variables:
|
|||||||
- "**/Cargo.toml"
|
- "**/Cargo.toml"
|
||||||
- "Cargo.lock"
|
- "Cargo.lock"
|
||||||
# database migrations
|
# database migrations
|
||||||
- "migrations"
|
- "migrations/**"
|
||||||
# typescript tests
|
# typescript tests
|
||||||
- "api_tests"
|
- "api_tests/**"
|
||||||
# config files and scripts used by ci
|
# config files and scripts used by ci
|
||||||
- ".woodpecker.yml"
|
- ".woodpecker.yml"
|
||||||
- ".rustfmt.toml"
|
- ".rustfmt.toml"
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
"eslint": "^8.40.0",
|
"eslint": "^8.40.0",
|
||||||
"eslint-plugin-prettier": "^4.0.0",
|
"eslint-plugin-prettier": "^4.0.0",
|
||||||
"jest": "^29.5.0",
|
"jest": "^29.5.0",
|
||||||
"lemmy-js-client": "0.18.3-rc.3",
|
"lemmy-js-client": "0.19.0-rc.2",
|
||||||
"prettier": "^3.0.0",
|
"prettier": "^3.0.0",
|
||||||
"ts-jest": "^29.1.0",
|
"ts-jest": "^29.1.0",
|
||||||
"typescript": "^5.0.4"
|
"typescript": "^5.0.4"
|
||||||
|
@ -707,6 +707,7 @@ export async function getPersonDetails(
|
|||||||
export async function deleteUser(api: API): Promise<DeleteAccountResponse> {
|
export async function deleteUser(api: API): Promise<DeleteAccountResponse> {
|
||||||
let form: DeleteAccount = {
|
let form: DeleteAccount = {
|
||||||
auth: api.auth,
|
auth: api.auth,
|
||||||
|
delete_content: true,
|
||||||
password,
|
password,
|
||||||
};
|
};
|
||||||
return api.client.deleteAccount(form);
|
return api.client.deleteAccount(form);
|
||||||
|
@ -2174,10 +2174,10 @@ kleur@^3.0.3:
|
|||||||
resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e"
|
resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e"
|
||||||
integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==
|
integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==
|
||||||
|
|
||||||
lemmy-js-client@0.18.3-rc.3:
|
lemmy-js-client@0.19.0-rc.2:
|
||||||
version "0.18.3-rc.3"
|
version "0.19.0-rc.2"
|
||||||
resolved "https://registry.yarnpkg.com/lemmy-js-client/-/lemmy-js-client-0.18.3-rc.3.tgz#fc6489eb141bd09558bca38d9e46b40771a29f37"
|
resolved "https://registry.yarnpkg.com/lemmy-js-client/-/lemmy-js-client-0.19.0-rc.2.tgz#c3cb511b27f92538909a2b91a0f8527b1abad958"
|
||||||
integrity sha512-njixgXk4uMU4gGifnljwhSe9Kf445C4wAXcXhtpTtwPPLXpHQgxA1RASMb9Uq4zblfE6nC2JbrAka8y8N2N/Bw==
|
integrity sha512-FXuf8s7bpBVkHL/OGWDb/0aGIrJ7uv3d4Xt1h6zmNDhw6MmmuD8RXgCHiS2jqhxjAEp96Dpl1NFXbpmKpix7tQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
cross-fetch "^3.1.5"
|
cross-fetch "^3.1.5"
|
||||||
form-data "^4.0.0"
|
form-data "^4.0.0"
|
||||||
|
@ -47,13 +47,7 @@ pub async fn ban_from_site(
|
|||||||
// Remove their data if that's desired
|
// Remove their data if that's desired
|
||||||
let remove_data = data.remove_data.unwrap_or(false);
|
let remove_data = data.remove_data.unwrap_or(false);
|
||||||
if remove_data {
|
if remove_data {
|
||||||
remove_user_data(
|
remove_user_data(person.id, &context).await?;
|
||||||
person.id,
|
|
||||||
&mut context.pool(),
|
|
||||||
context.settings(),
|
|
||||||
context.client(),
|
|
||||||
)
|
|
||||||
.await?;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mod tables
|
// Mod tables
|
||||||
|
@ -33,24 +33,14 @@ impl Perform for PurgeCommunity {
|
|||||||
let community = Community::read(&mut context.pool(), community_id).await?;
|
let community = Community::read(&mut context.pool(), community_id).await?;
|
||||||
|
|
||||||
if let Some(banner) = community.banner {
|
if let Some(banner) = community.banner {
|
||||||
purge_image_from_pictrs(context.client(), context.settings(), &banner)
|
purge_image_from_pictrs(&banner, context).await.ok();
|
||||||
.await
|
|
||||||
.ok();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(icon) = community.icon {
|
if let Some(icon) = community.icon {
|
||||||
purge_image_from_pictrs(context.client(), context.settings(), &icon)
|
purge_image_from_pictrs(&icon, context).await.ok();
|
||||||
.await
|
|
||||||
.ok();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
purge_image_posts_for_community(
|
purge_image_posts_for_community(community_id, context).await?;
|
||||||
community_id,
|
|
||||||
&mut context.pool(),
|
|
||||||
context.settings(),
|
|
||||||
context.client(),
|
|
||||||
)
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
Community::delete(&mut context.pool(), community_id).await?;
|
Community::delete(&mut context.pool(), community_id).await?;
|
||||||
|
|
||||||
|
@ -32,24 +32,14 @@ impl Perform for PurgePerson {
|
|||||||
let person = Person::read(&mut context.pool(), person_id).await?;
|
let person = Person::read(&mut context.pool(), person_id).await?;
|
||||||
|
|
||||||
if let Some(banner) = person.banner {
|
if let Some(banner) = person.banner {
|
||||||
purge_image_from_pictrs(context.client(), context.settings(), &banner)
|
purge_image_from_pictrs(&banner, context).await.ok();
|
||||||
.await
|
|
||||||
.ok();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(avatar) = person.avatar {
|
if let Some(avatar) = person.avatar {
|
||||||
purge_image_from_pictrs(context.client(), context.settings(), &avatar)
|
purge_image_from_pictrs(&avatar, context).await.ok();
|
||||||
.await
|
|
||||||
.ok();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
purge_image_posts_for_person(
|
purge_image_posts_for_person(person_id, context).await?;
|
||||||
person_id,
|
|
||||||
&mut context.pool(),
|
|
||||||
context.settings(),
|
|
||||||
context.client(),
|
|
||||||
)
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
Person::delete(&mut context.pool(), person_id).await?;
|
Person::delete(&mut context.pool(), person_id).await?;
|
||||||
|
|
||||||
|
@ -34,15 +34,11 @@ impl Perform for PurgePost {
|
|||||||
|
|
||||||
// Purge image
|
// Purge image
|
||||||
if let Some(url) = post.url {
|
if let Some(url) = post.url {
|
||||||
purge_image_from_pictrs(context.client(), context.settings(), &url)
|
purge_image_from_pictrs(&url, context).await.ok();
|
||||||
.await
|
|
||||||
.ok();
|
|
||||||
}
|
}
|
||||||
// Purge thumbnail
|
// Purge thumbnail
|
||||||
if let Some(thumbnail_url) = post.thumbnail_url {
|
if let Some(thumbnail_url) = post.thumbnail_url {
|
||||||
purge_image_from_pictrs(context.client(), context.settings(), &thumbnail_url)
|
purge_image_from_pictrs(&thumbnail_url, context).await.ok();
|
||||||
.await
|
|
||||||
.ok();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let community_id = post.community_id;
|
let community_id = post.community_id;
|
||||||
|
@ -3,22 +3,20 @@ use actix_web::{
|
|||||||
web::Data,
|
web::Data,
|
||||||
HttpResponse,
|
HttpResponse,
|
||||||
};
|
};
|
||||||
use chrono::{DateTime, FixedOffset};
|
|
||||||
use lemmy_api_common::context::LemmyContext;
|
use lemmy_api_common::context::LemmyContext;
|
||||||
use lemmy_db_schema::{newtypes::DbUrl, source::post::Post};
|
use lemmy_db_schema::{newtypes::DbUrl, source::post::Post};
|
||||||
use lemmy_utils::error::LemmyResult;
|
use lemmy_utils::error::LemmyResult;
|
||||||
use sitemap_rs::{url::Url, url_set::UrlSet};
|
use sitemap_rs::{url::Url, url_set::UrlSet};
|
||||||
use tracing::info;
|
use tracing::info;
|
||||||
|
|
||||||
async fn generate_urlset(posts: Vec<(DbUrl, chrono::NaiveDateTime)>) -> LemmyResult<UrlSet> {
|
async fn generate_urlset(
|
||||||
|
posts: Vec<(DbUrl, chrono::DateTime<chrono::Utc>)>,
|
||||||
|
) -> LemmyResult<UrlSet> {
|
||||||
let urls = posts
|
let urls = posts
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map_while(|post| {
|
.map_while(|post| {
|
||||||
Url::builder(post.0.to_string())
|
Url::builder(post.0.to_string())
|
||||||
.last_modified(DateTime::from_utc(
|
.last_modified(post.1.into())
|
||||||
post.1,
|
|
||||||
FixedOffset::east_opt(0).expect("Error setting timezone offset"), // TODO what is the proper timezone offset here?
|
|
||||||
))
|
|
||||||
.build()
|
.build()
|
||||||
.ok()
|
.ok()
|
||||||
})
|
})
|
||||||
@ -48,27 +46,29 @@ pub(crate) mod tests {
|
|||||||
#![allow(clippy::unwrap_used)]
|
#![allow(clippy::unwrap_used)]
|
||||||
|
|
||||||
use crate::sitemap::generate_urlset;
|
use crate::sitemap::generate_urlset;
|
||||||
use chrono::{NaiveDate, NaiveDateTime};
|
use chrono::{DateTime, NaiveDate, Utc};
|
||||||
use elementtree::Element;
|
use elementtree::Element;
|
||||||
use lemmy_db_schema::newtypes::DbUrl;
|
use lemmy_db_schema::newtypes::DbUrl;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn test_generate_urlset() {
|
async fn test_generate_urlset() {
|
||||||
let posts: Vec<(DbUrl, NaiveDateTime)> = vec![
|
let posts: Vec<(DbUrl, DateTime<Utc>)> = vec![
|
||||||
(
|
(
|
||||||
Url::parse("https://example.com").unwrap().into(),
|
Url::parse("https://example.com").unwrap().into(),
|
||||||
NaiveDate::from_ymd_opt(2022, 12, 1)
|
NaiveDate::from_ymd_opt(2022, 12, 1)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.and_hms_opt(9, 10, 11)
|
.and_hms_opt(9, 10, 11)
|
||||||
.unwrap(),
|
.unwrap()
|
||||||
|
.and_utc(),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
Url::parse("https://lemmy.ml").unwrap().into(),
|
Url::parse("https://lemmy.ml").unwrap().into(),
|
||||||
NaiveDate::from_ymd_opt(2023, 1, 1)
|
NaiveDate::from_ymd_opt(2023, 1, 1)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.and_hms_opt(1, 2, 3)
|
.and_hms_opt(1, 2, 3)
|
||||||
.unwrap(),
|
.unwrap()
|
||||||
|
.and_utc(),
|
||||||
),
|
),
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -365,6 +365,7 @@ pub struct CommentReplyResponse {
|
|||||||
/// Delete your account.
|
/// Delete your account.
|
||||||
pub struct DeleteAccount {
|
pub struct DeleteAccount {
|
||||||
pub password: Sensitive<String>,
|
pub password: Sensitive<String>,
|
||||||
|
pub delete_content: bool,
|
||||||
pub auth: Sensitive<String>,
|
pub auth: Sensitive<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use crate::post::SiteMetadata;
|
use crate::{context::LemmyContext, post::SiteMetadata};
|
||||||
use encoding::{all::encodings, DecoderTrap};
|
use encoding::{all::encodings, DecoderTrap};
|
||||||
use lemmy_db_schema::newtypes::DbUrl;
|
use lemmy_db_schema::newtypes::DbUrl;
|
||||||
use lemmy_utils::{
|
use lemmy_utils::{
|
||||||
@ -150,12 +150,11 @@ pub(crate) async fn fetch_pictrs(
|
|||||||
/// - It might not be an image
|
/// - It might not be an image
|
||||||
/// - Pictrs might not be set up
|
/// - Pictrs might not be set up
|
||||||
pub async fn purge_image_from_pictrs(
|
pub async fn purge_image_from_pictrs(
|
||||||
client: &ClientWithMiddleware,
|
|
||||||
settings: &Settings,
|
|
||||||
image_url: &Url,
|
image_url: &Url,
|
||||||
|
context: &LemmyContext,
|
||||||
) -> Result<(), LemmyError> {
|
) -> Result<(), LemmyError> {
|
||||||
let pictrs_config = settings.pictrs_config()?;
|
let pictrs_config = context.settings().pictrs_config()?;
|
||||||
is_image_content_type(client, image_url).await?;
|
is_image_content_type(context.client(), image_url).await?;
|
||||||
|
|
||||||
let alias = image_url
|
let alias = image_url
|
||||||
.path_segments()
|
.path_segments()
|
||||||
@ -168,7 +167,8 @@ pub async fn purge_image_from_pictrs(
|
|||||||
let pictrs_api_key = pictrs_config
|
let pictrs_api_key = pictrs_config
|
||||||
.api_key
|
.api_key
|
||||||
.ok_or(LemmyErrorType::PictrsApiKeyNotProvided)?;
|
.ok_or(LemmyErrorType::PictrsApiKeyNotProvided)?;
|
||||||
let response = client
|
let response = context
|
||||||
|
.client()
|
||||||
.post(&purge_url)
|
.post(&purge_url)
|
||||||
.timeout(REQWEST_TIMEOUT)
|
.timeout(REQWEST_TIMEOUT)
|
||||||
.header("x-api-token", pictrs_api_key)
|
.header("x-api-token", pictrs_api_key)
|
||||||
|
@ -58,7 +58,7 @@ pub enum SendActivityData {
|
|||||||
CreatePrivateMessage(PrivateMessageView),
|
CreatePrivateMessage(PrivateMessageView),
|
||||||
UpdatePrivateMessage(PrivateMessageView),
|
UpdatePrivateMessage(PrivateMessageView),
|
||||||
DeletePrivateMessage(Person, PrivateMessage, bool),
|
DeletePrivateMessage(Person, PrivateMessage, bool),
|
||||||
DeleteUser(Person),
|
DeleteUser(Person, bool),
|
||||||
CreateReport(Url, Person, Community, String),
|
CreateReport(Url, Person, Community, String),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,7 +42,6 @@ use lemmy_utils::{
|
|||||||
utils::slurs::build_slur_regex,
|
utils::slurs::build_slur_regex,
|
||||||
};
|
};
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use reqwest_middleware::ClientWithMiddleware;
|
|
||||||
use rosetta_i18n::{Language, LanguageId};
|
use rosetta_i18n::{Language, LanguageId};
|
||||||
use tracing::warn;
|
use tracing::warn;
|
||||||
use url::{ParseError, Url};
|
use url::{ParseError, Url};
|
||||||
@ -529,19 +528,16 @@ pub fn check_private_instance_and_federation_enabled(
|
|||||||
|
|
||||||
pub async fn purge_image_posts_for_person(
|
pub async fn purge_image_posts_for_person(
|
||||||
banned_person_id: PersonId,
|
banned_person_id: PersonId,
|
||||||
pool: &mut DbPool<'_>,
|
context: &LemmyContext,
|
||||||
settings: &Settings,
|
|
||||||
client: &ClientWithMiddleware,
|
|
||||||
) -> Result<(), LemmyError> {
|
) -> Result<(), LemmyError> {
|
||||||
|
let pool = &mut context.pool();
|
||||||
let posts = Post::fetch_pictrs_posts_for_creator(pool, banned_person_id).await?;
|
let posts = Post::fetch_pictrs_posts_for_creator(pool, banned_person_id).await?;
|
||||||
for post in posts {
|
for post in posts {
|
||||||
if let Some(url) = post.url {
|
if let Some(url) = post.url {
|
||||||
purge_image_from_pictrs(client, settings, &url).await.ok();
|
purge_image_from_pictrs(&url, context).await.ok();
|
||||||
}
|
}
|
||||||
if let Some(thumbnail_url) = post.thumbnail_url {
|
if let Some(thumbnail_url) = post.thumbnail_url {
|
||||||
purge_image_from_pictrs(client, settings, &thumbnail_url)
|
purge_image_from_pictrs(&thumbnail_url, context).await.ok();
|
||||||
.await
|
|
||||||
.ok();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -552,19 +548,16 @@ pub async fn purge_image_posts_for_person(
|
|||||||
|
|
||||||
pub async fn purge_image_posts_for_community(
|
pub async fn purge_image_posts_for_community(
|
||||||
banned_community_id: CommunityId,
|
banned_community_id: CommunityId,
|
||||||
pool: &mut DbPool<'_>,
|
context: &LemmyContext,
|
||||||
settings: &Settings,
|
|
||||||
client: &ClientWithMiddleware,
|
|
||||||
) -> Result<(), LemmyError> {
|
) -> Result<(), LemmyError> {
|
||||||
|
let pool = &mut context.pool();
|
||||||
let posts = Post::fetch_pictrs_posts_for_community(pool, banned_community_id).await?;
|
let posts = Post::fetch_pictrs_posts_for_community(pool, banned_community_id).await?;
|
||||||
for post in posts {
|
for post in posts {
|
||||||
if let Some(url) = post.url {
|
if let Some(url) = post.url {
|
||||||
purge_image_from_pictrs(client, settings, &url).await.ok();
|
purge_image_from_pictrs(&url, context).await.ok();
|
||||||
}
|
}
|
||||||
if let Some(thumbnail_url) = post.thumbnail_url {
|
if let Some(thumbnail_url) = post.thumbnail_url {
|
||||||
purge_image_from_pictrs(client, settings, &thumbnail_url)
|
purge_image_from_pictrs(&thumbnail_url, context).await.ok();
|
||||||
.await
|
|
||||||
.ok();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -575,21 +568,16 @@ pub async fn purge_image_posts_for_community(
|
|||||||
|
|
||||||
pub async fn remove_user_data(
|
pub async fn remove_user_data(
|
||||||
banned_person_id: PersonId,
|
banned_person_id: PersonId,
|
||||||
pool: &mut DbPool<'_>,
|
context: &LemmyContext,
|
||||||
settings: &Settings,
|
|
||||||
client: &ClientWithMiddleware,
|
|
||||||
) -> Result<(), LemmyError> {
|
) -> Result<(), LemmyError> {
|
||||||
|
let pool = &mut context.pool();
|
||||||
// Purge user images
|
// Purge user images
|
||||||
let person = Person::read(pool, banned_person_id).await?;
|
let person = Person::read(pool, banned_person_id).await?;
|
||||||
if let Some(avatar) = person.avatar {
|
if let Some(avatar) = person.avatar {
|
||||||
purge_image_from_pictrs(client, settings, &avatar)
|
purge_image_from_pictrs(&avatar, context).await.ok();
|
||||||
.await
|
|
||||||
.ok();
|
|
||||||
}
|
}
|
||||||
if let Some(banner) = person.banner {
|
if let Some(banner) = person.banner {
|
||||||
purge_image_from_pictrs(client, settings, &banner)
|
purge_image_from_pictrs(&banner, context).await.ok();
|
||||||
.await
|
|
||||||
.ok();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the fields to None
|
// Update the fields to None
|
||||||
@ -608,7 +596,7 @@ pub async fn remove_user_data(
|
|||||||
Post::update_removed_for_creator(pool, banned_person_id, None, true).await?;
|
Post::update_removed_for_creator(pool, banned_person_id, None, true).await?;
|
||||||
|
|
||||||
// Purge image posts
|
// Purge image posts
|
||||||
purge_image_posts_for_person(banned_person_id, pool, settings, client).await?;
|
purge_image_posts_for_person(banned_person_id, context).await?;
|
||||||
|
|
||||||
// Communities
|
// Communities
|
||||||
// Remove all communities where they're the top mod
|
// Remove all communities where they're the top mod
|
||||||
@ -635,12 +623,10 @@ pub async fn remove_user_data(
|
|||||||
|
|
||||||
// Delete the community images
|
// Delete the community images
|
||||||
if let Some(icon) = first_mod_community.community.icon {
|
if let Some(icon) = first_mod_community.community.icon {
|
||||||
purge_image_from_pictrs(client, settings, &icon).await.ok();
|
purge_image_from_pictrs(&icon, context).await.ok();
|
||||||
}
|
}
|
||||||
if let Some(banner) = first_mod_community.community.banner {
|
if let Some(banner) = first_mod_community.community.banner {
|
||||||
purge_image_from_pictrs(client, settings, &banner)
|
purge_image_from_pictrs(&banner, context).await.ok();
|
||||||
.await
|
|
||||||
.ok();
|
|
||||||
}
|
}
|
||||||
// Update the fields to None
|
// Update the fields to None
|
||||||
Community::update(
|
Community::update(
|
||||||
@ -695,23 +681,18 @@ pub async fn remove_user_data_in_community(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn delete_user_account(
|
pub async fn purge_user_account(
|
||||||
person_id: PersonId,
|
person_id: PersonId,
|
||||||
pool: &mut DbPool<'_>,
|
context: &LemmyContext,
|
||||||
settings: &Settings,
|
|
||||||
client: &ClientWithMiddleware,
|
|
||||||
) -> Result<(), LemmyError> {
|
) -> Result<(), LemmyError> {
|
||||||
|
let pool = &mut context.pool();
|
||||||
// Delete their images
|
// Delete their images
|
||||||
let person = Person::read(pool, person_id).await?;
|
let person = Person::read(pool, person_id).await?;
|
||||||
if let Some(avatar) = person.avatar {
|
if let Some(avatar) = person.avatar {
|
||||||
purge_image_from_pictrs(client, settings, &avatar)
|
purge_image_from_pictrs(&avatar, context).await.ok();
|
||||||
.await
|
|
||||||
.ok();
|
|
||||||
}
|
}
|
||||||
if let Some(banner) = person.banner {
|
if let Some(banner) = person.banner {
|
||||||
purge_image_from_pictrs(client, settings, &banner)
|
purge_image_from_pictrs(&banner, context).await.ok();
|
||||||
.await
|
|
||||||
.ok();
|
|
||||||
}
|
}
|
||||||
// No need to update avatar and banner, those are handled in Person::delete_account
|
// No need to update avatar and banner, those are handled in Person::delete_account
|
||||||
|
|
||||||
@ -726,7 +707,7 @@ pub async fn delete_user_account(
|
|||||||
.with_lemmy_type(LemmyErrorType::CouldntUpdatePost)?;
|
.with_lemmy_type(LemmyErrorType::CouldntUpdatePost)?;
|
||||||
|
|
||||||
// Purge image posts
|
// Purge image posts
|
||||||
purge_image_posts_for_person(person_id, pool, settings, client).await?;
|
purge_image_posts_for_person(person_id, context).await?;
|
||||||
|
|
||||||
// Leave communities they mod
|
// Leave communities they mod
|
||||||
CommunityModerator::leave_all_communities(pool, person_id).await?;
|
CommunityModerator::leave_all_communities(pool, person_id).await?;
|
||||||
|
@ -5,8 +5,9 @@ use lemmy_api_common::{
|
|||||||
context::LemmyContext,
|
context::LemmyContext,
|
||||||
person::{DeleteAccount, DeleteAccountResponse},
|
person::{DeleteAccount, DeleteAccountResponse},
|
||||||
send_activity::{ActivityChannel, SendActivityData},
|
send_activity::{ActivityChannel, SendActivityData},
|
||||||
utils::local_user_view_from_jwt,
|
utils::{local_user_view_from_jwt, purge_user_account},
|
||||||
};
|
};
|
||||||
|
use lemmy_db_schema::source::person::Person;
|
||||||
use lemmy_utils::error::{LemmyError, LemmyErrorType};
|
use lemmy_utils::error::{LemmyError, LemmyErrorType};
|
||||||
|
|
||||||
#[tracing::instrument(skip(context))]
|
#[tracing::instrument(skip(context))]
|
||||||
@ -26,8 +27,14 @@ pub async fn delete_account(
|
|||||||
return Err(LemmyErrorType::IncorrectLogin)?;
|
return Err(LemmyErrorType::IncorrectLogin)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if data.delete_content {
|
||||||
|
purge_user_account(local_user_view.person.id, &context).await?;
|
||||||
|
} else {
|
||||||
|
Person::delete_account(&mut context.pool(), local_user_view.person.id).await?;
|
||||||
|
}
|
||||||
|
|
||||||
ActivityChannel::submit_activity(
|
ActivityChannel::submit_activity(
|
||||||
SendActivityData::DeleteUser(local_user_view.person),
|
SendActivityData::DeleteUser(local_user_view.person, data.delete_content),
|
||||||
&context,
|
&context,
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
@ -166,13 +166,7 @@ impl ActivityHandler for BlockUser {
|
|||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
if self.remove_data.unwrap_or(false) {
|
if self.remove_data.unwrap_or(false) {
|
||||||
remove_user_data(
|
remove_user_data(blocked_person.id, context).await?;
|
||||||
blocked_person.id,
|
|
||||||
&mut context.pool(),
|
|
||||||
context.settings(),
|
|
||||||
context.client(),
|
|
||||||
)
|
|
||||||
.await?;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// write mod log
|
// write mod log
|
||||||
|
@ -10,20 +10,17 @@ use activitypub_federation::{
|
|||||||
protocol::verification::verify_urls_match,
|
protocol::verification::verify_urls_match,
|
||||||
traits::{ActivityHandler, Actor},
|
traits::{ActivityHandler, Actor},
|
||||||
};
|
};
|
||||||
use lemmy_api_common::{context::LemmyContext, utils::delete_user_account};
|
use lemmy_api_common::{context::LemmyContext, utils::purge_user_account};
|
||||||
use lemmy_db_schema::source::{activity::ActivitySendTargets, person::Person};
|
use lemmy_db_schema::source::{activity::ActivitySendTargets, person::Person};
|
||||||
use lemmy_utils::error::LemmyError;
|
use lemmy_utils::error::LemmyError;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
pub async fn delete_user(person: Person, context: Data<LemmyContext>) -> Result<(), LemmyError> {
|
pub async fn delete_user(
|
||||||
|
person: Person,
|
||||||
|
delete_content: bool,
|
||||||
|
context: Data<LemmyContext>,
|
||||||
|
) -> Result<(), LemmyError> {
|
||||||
let actor: ApubPerson = person.into();
|
let actor: ApubPerson = person.into();
|
||||||
delete_user_account(
|
|
||||||
actor.id,
|
|
||||||
&mut context.pool(),
|
|
||||||
context.settings(),
|
|
||||||
context.client(),
|
|
||||||
)
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
let id = generate_activity_id(
|
let id = generate_activity_id(
|
||||||
DeleteType::Delete,
|
DeleteType::Delete,
|
||||||
@ -36,6 +33,7 @@ pub async fn delete_user(person: Person, context: Data<LemmyContext>) -> Result<
|
|||||||
kind: DeleteType::Delete,
|
kind: DeleteType::Delete,
|
||||||
id: id.clone(),
|
id: id.clone(),
|
||||||
cc: vec![],
|
cc: vec![],
|
||||||
|
remove_data: Some(delete_content),
|
||||||
};
|
};
|
||||||
|
|
||||||
let inboxes = ActivitySendTargets::to_all_instances();
|
let inboxes = ActivitySendTargets::to_all_instances();
|
||||||
@ -69,13 +67,11 @@ impl ActivityHandler for DeleteUser {
|
|||||||
|
|
||||||
async fn receive(self, context: &Data<Self::DataType>) -> Result<(), LemmyError> {
|
async fn receive(self, context: &Data<Self::DataType>) -> Result<(), LemmyError> {
|
||||||
let actor = self.actor.dereference(context).await?;
|
let actor = self.actor.dereference(context).await?;
|
||||||
delete_user_account(
|
if self.remove_data.unwrap_or(false) {
|
||||||
actor.id,
|
purge_user_account(actor.id, context).await?;
|
||||||
&mut context.pool(),
|
} else {
|
||||||
context.settings(),
|
Person::delete_account(&mut context.pool(), actor.id).await?;
|
||||||
context.client(),
|
}
|
||||||
)
|
|
||||||
.await?;
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -327,7 +327,7 @@ pub async fn match_outgoing_activities(
|
|||||||
DeletePrivateMessage(person, pm, deleted) => {
|
DeletePrivateMessage(person, pm, deleted) => {
|
||||||
send_apub_delete_private_message(&person.into(), pm, deleted, context).await
|
send_apub_delete_private_message(&person.into(), pm, deleted, context).await
|
||||||
}
|
}
|
||||||
DeleteUser(person) => delete_user(person, context).await,
|
DeleteUser(person, delete_content) => delete_user(person, delete_content, context).await,
|
||||||
CreateReport(url, actor, community, reason) => {
|
CreateReport(url, actor, community, reason) => {
|
||||||
Report::send(ObjectId::from(url), actor, community, reason, context).await
|
Report::send(ObjectId::from(url), actor, community, reason, context).await
|
||||||
}
|
}
|
||||||
|
@ -23,4 +23,6 @@ pub struct DeleteUser {
|
|||||||
#[serde(deserialize_with = "deserialize_one_or_many", default)]
|
#[serde(deserialize_with = "deserialize_one_or_many", default)]
|
||||||
#[serde(skip_serializing_if = "Vec::is_empty")]
|
#[serde(skip_serializing_if = "Vec::is_empty")]
|
||||||
pub(crate) cc: Vec<Url>,
|
pub(crate) cc: Vec<Url>,
|
||||||
|
/// Nonstandard field. If present, all content from the user should be deleted along with the account
|
||||||
|
pub(crate) remove_data: Option<bool>,
|
||||||
}
|
}
|
||||||
|
@ -101,16 +101,16 @@ impl Post {
|
|||||||
|
|
||||||
pub async fn list_for_sitemap(
|
pub async fn list_for_sitemap(
|
||||||
pool: &mut DbPool<'_>,
|
pool: &mut DbPool<'_>,
|
||||||
) -> Result<Vec<(DbUrl, chrono::NaiveDateTime)>, Error> {
|
) -> Result<Vec<(DbUrl, chrono::DateTime<Utc>)>, Error> {
|
||||||
let conn = &mut get_conn(pool).await?;
|
let conn = &mut get_conn(pool).await?;
|
||||||
post
|
post
|
||||||
.select((ap_id, coalesce(updated, published)))
|
.select((ap_id, coalesce(updated, published)))
|
||||||
.filter(local)
|
.filter(local.eq(true))
|
||||||
.filter(deleted.eq(false))
|
.filter(deleted.eq(false))
|
||||||
.filter(removed.eq(false))
|
.filter(removed.eq(false))
|
||||||
.filter(published.ge(Utc::now().naive_utc() - Duration::days(1)))
|
.filter(published.ge(Utc::now().naive_utc() - Duration::days(1)))
|
||||||
.order(published.desc())
|
.order(published.desc())
|
||||||
.load::<(DbUrl, chrono::NaiveDateTime)>(conn)
|
.load::<(DbUrl, chrono::DateTime<Utc>)>(conn)
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user