mirror of https://github.com/LemmyNet/lemmy.git
add config option
parent
f057abff71
commit
986913d250
|
@ -44,7 +44,13 @@
|
||||||
# Set a custom pictrs API key. ( Required for deleting images )
|
# Set a custom pictrs API key. ( Required for deleting images )
|
||||||
api_key: "string"
|
api_key: "string"
|
||||||
# Cache remote images
|
# Cache remote images
|
||||||
cache_remote_images: true
|
cache_remote_thumbnails: true
|
||||||
|
# If enabled, all images from remote domains are rewritten to pass through `/api/v3/image_proxy`.
|
||||||
|
# This improves privacy as users don't expose their IP to untrusted servers, and decreases load
|
||||||
|
# on other servers. However it causes more load for the local server.
|
||||||
|
#
|
||||||
|
# Requires pict-rs 0.5
|
||||||
|
image_proxy: false
|
||||||
}
|
}
|
||||||
# Email sending configuration. All options except login/password are mandatory
|
# Email sending configuration. All options except login/password are mandatory
|
||||||
email: {
|
email: {
|
||||||
|
|
|
@ -124,7 +124,7 @@ pub(crate) async fn fetch_pictrs(
|
||||||
let pictrs_config = settings.pictrs_config()?;
|
let pictrs_config = settings.pictrs_config()?;
|
||||||
is_image_content_type(client, image_url).await?;
|
is_image_content_type(client, image_url).await?;
|
||||||
|
|
||||||
if pictrs_config.cache_remote_images {
|
if pictrs_config.cache_remote_thumbnails {
|
||||||
// fetch remote non-pictrs images for persistent thumbnail link
|
// fetch remote non-pictrs images for persistent thumbnail link
|
||||||
let fetch_url = format!(
|
let fetch_url = format!(
|
||||||
"{}image/download?url={}",
|
"{}image/download?url={}",
|
||||||
|
|
|
@ -12,7 +12,6 @@ use lemmy_api_common::{
|
||||||
honeypot_check,
|
honeypot_check,
|
||||||
local_site_to_slur_regex,
|
local_site_to_slur_regex,
|
||||||
mark_post_as_read,
|
mark_post_as_read,
|
||||||
process_markdown_opt,
|
|
||||||
EndpointType,
|
EndpointType,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -32,13 +31,14 @@ use lemmy_utils::{
|
||||||
error::{LemmyError, LemmyErrorExt, LemmyErrorType},
|
error::{LemmyError, LemmyErrorExt, LemmyErrorType},
|
||||||
spawn_try_task,
|
spawn_try_task,
|
||||||
utils::{
|
utils::{
|
||||||
slurs::check_slurs,
|
slurs::{check_slurs},
|
||||||
validation::{check_url_scheme, clean_url_params, is_valid_body_field, is_valid_post_title},
|
validation::{check_url_scheme, clean_url_params, is_valid_body_field, is_valid_post_title},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use tracing::Instrument;
|
use tracing::Instrument;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
use webmention::{Webmention, WebmentionError};
|
use webmention::{Webmention, WebmentionError};
|
||||||
|
use lemmy_api_common::utils::process_markdown_opt;
|
||||||
|
|
||||||
#[tracing::instrument(skip(context))]
|
#[tracing::instrument(skip(context))]
|
||||||
pub async fn create_post(
|
pub async fn create_post(
|
||||||
|
@ -53,6 +53,9 @@ pub async fn create_post(
|
||||||
let body = process_markdown_opt(&data.body, &slur_regex, &context).await?;
|
let body = process_markdown_opt(&data.body, &slur_regex, &context).await?;
|
||||||
honeypot_check(&data.honeypot)?;
|
honeypot_check(&data.honeypot)?;
|
||||||
|
|
||||||
|
let data_url = data.url.as_ref();
|
||||||
|
let url = data_url.map(clean_url_params).map(Into::into); // TODO no good way to handle a "clear"
|
||||||
|
|
||||||
is_valid_post_title(&data.name)?;
|
is_valid_post_title(&data.name)?;
|
||||||
is_valid_body_field(&body, true)?;
|
is_valid_body_field(&body, true)?;
|
||||||
check_url_scheme(&data.url)?;
|
check_url_scheme(&data.url)?;
|
||||||
|
@ -80,29 +83,12 @@ pub async fn create_post(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fetch post links and pictrs cached image
|
// Fetch post links and pictrs cached image
|
||||||
let (metadata_res, thumbnail_url) = fetch_site_data(
|
let (metadata_res, thumbnail_url) =
|
||||||
context.client(),
|
fetch_site_data(context.client(), context.settings(), data_url, true).await;
|
||||||
context.settings(),
|
|
||||||
data.url.as_ref(),
|
|
||||||
true,
|
|
||||||
)
|
|
||||||
.await;
|
|
||||||
let (embed_title, embed_description, embed_video_url) = metadata_res
|
let (embed_title, embed_description, embed_video_url) = metadata_res
|
||||||
.map(|u| (u.title, u.description, u.embed_video_url))
|
.map(|u| (u.title, u.description, u.embed_video_url))
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
|
|
||||||
// TODO No good way to handle a clear.
|
|
||||||
// Issue link: https://github.com/LemmyNet/lemmy/issues/2287
|
|
||||||
let url = data.url.as_ref().map(clean_url_params).map(Into::into);
|
|
||||||
|
|
||||||
// TODO: not sure how to get this working
|
|
||||||
/*
|
|
||||||
let url_is_image = todo!();
|
|
||||||
if url_is_image {
|
|
||||||
proxy_image_link_opt(url, &context).await?;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Only need to check if language is allowed in case user set it explicitly. When using default
|
// Only need to check if language is allowed in case user set it explicitly. When using default
|
||||||
// language, it already only returns allowed languages.
|
// language, it already only returns allowed languages.
|
||||||
CommunityLanguage::is_allowed_community_language(
|
CommunityLanguage::is_allowed_community_language(
|
||||||
|
|
|
@ -6,7 +6,7 @@ use lemmy_api_common::{
|
||||||
post::{EditPost, PostResponse},
|
post::{EditPost, PostResponse},
|
||||||
request::fetch_site_data,
|
request::fetch_site_data,
|
||||||
send_activity::{ActivityChannel, SendActivityData},
|
send_activity::{ActivityChannel, SendActivityData},
|
||||||
utils::{check_community_user_action, local_site_to_slur_regex, process_markdown_opt},
|
utils::{check_community_user_action, local_site_to_slur_regex},
|
||||||
};
|
};
|
||||||
use lemmy_db_schema::{
|
use lemmy_db_schema::{
|
||||||
source::{
|
source::{
|
||||||
|
@ -26,6 +26,7 @@ use lemmy_utils::{
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
|
use lemmy_api_common::utils::process_markdown_opt;
|
||||||
|
|
||||||
#[tracing::instrument(skip(context))]
|
#[tracing::instrument(skip(context))]
|
||||||
pub async fn update_post(
|
pub async fn update_post(
|
||||||
|
@ -35,6 +36,12 @@ pub async fn update_post(
|
||||||
) -> Result<Json<PostResponse>, LemmyError> {
|
) -> Result<Json<PostResponse>, LemmyError> {
|
||||||
let local_site = LocalSite::read(&mut context.pool()).await?;
|
let local_site = LocalSite::read(&mut context.pool()).await?;
|
||||||
|
|
||||||
|
let data_url = data.url.as_ref();
|
||||||
|
|
||||||
|
// TODO No good way to handle a clear.
|
||||||
|
// Issue link: https://github.com/LemmyNet/lemmy/issues/2287
|
||||||
|
let url = Some(data_url.map(clean_url_params).map(Into::into));
|
||||||
|
|
||||||
let slur_regex = local_site_to_slur_regex(&local_site);
|
let slur_regex = local_site_to_slur_regex(&local_site);
|
||||||
check_slurs_opt(&data.name, &slur_regex)?;
|
check_slurs_opt(&data.name, &slur_regex)?;
|
||||||
let body = process_markdown_opt(&data.body, &slur_regex, &context).await?;
|
let body = process_markdown_opt(&data.body, &slur_regex, &context).await?;
|
||||||
|
@ -69,19 +76,6 @@ pub async fn update_post(
|
||||||
.map(|u| (Some(u.title), Some(u.description), Some(u.embed_video_url)))
|
.map(|u| (Some(u.title), Some(u.description), Some(u.embed_video_url)))
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
|
|
||||||
// TODO No good way to handle a clear.
|
|
||||||
// Issue link: https://github.com/LemmyNet/lemmy/issues/2287
|
|
||||||
let url = Some(data.url.as_ref().map(clean_url_params).map(Into::into));
|
|
||||||
|
|
||||||
// TODO: not sure how to get this working
|
|
||||||
/*
|
|
||||||
let url_is_image = todo!();
|
|
||||||
if url_is_image {
|
|
||||||
data_url = proxy_image_link_opt(url, &context).await?;
|
|
||||||
}
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
let language_id = data.language_id;
|
let language_id = data.language_id;
|
||||||
CommunityLanguage::is_allowed_community_language(
|
CommunityLanguage::is_allowed_community_language(
|
||||||
&mut context.pool(),
|
&mut context.pool(),
|
||||||
|
|
|
@ -25,12 +25,7 @@ use html2text::{from_read_with_decorator, render::text_renderer::TrivialDecorato
|
||||||
use lemmy_api_common::{
|
use lemmy_api_common::{
|
||||||
context::LemmyContext,
|
context::LemmyContext,
|
||||||
request::fetch_site_data,
|
request::fetch_site_data,
|
||||||
utils::{
|
utils::{is_mod_or_admin, local_site_opt_to_sensitive, local_site_opt_to_slur_regex},
|
||||||
is_mod_or_admin,
|
|
||||||
local_site_opt_to_sensitive,
|
|
||||||
local_site_opt_to_slur_regex,
|
|
||||||
process_markdown_opt,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
use lemmy_db_schema::{
|
use lemmy_db_schema::{
|
||||||
self,
|
self,
|
||||||
|
@ -45,11 +40,16 @@ use lemmy_db_schema::{
|
||||||
};
|
};
|
||||||
use lemmy_utils::{
|
use lemmy_utils::{
|
||||||
error::LemmyError,
|
error::LemmyError,
|
||||||
utils::{markdown::markdown_to_html, slurs::check_slurs_opt, validation::check_url_scheme},
|
utils::{
|
||||||
|
markdown::markdown_to_html,
|
||||||
|
slurs::{check_slurs_opt},
|
||||||
|
validation::check_url_scheme,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use stringreader::StringReader;
|
use stringreader::StringReader;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
use lemmy_api_common::utils::process_markdown_opt;
|
||||||
|
|
||||||
const MAX_TITLE_LENGTH: usize = 200;
|
const MAX_TITLE_LENGTH: usize = 200;
|
||||||
|
|
||||||
|
|
|
@ -1,29 +1,17 @@
|
||||||
use actix_web::{
|
use actix_web::{web, web::Query, HttpResponse};
|
||||||
web,
|
|
||||||
web::{Query, ServiceConfig},
|
|
||||||
HttpResponse,
|
|
||||||
};
|
|
||||||
use lemmy_api_common::context::LemmyContext;
|
use lemmy_api_common::context::LemmyContext;
|
||||||
use lemmy_db_schema::source::images::RemoteImage;
|
use lemmy_db_schema::source::images::RemoteImage;
|
||||||
use lemmy_utils::{error::LemmyResult, rate_limit::RateLimitCell};
|
use lemmy_utils::error::LemmyResult;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
use urlencoding::decode;
|
use urlencoding::decode;
|
||||||
|
|
||||||
pub fn config(cfg: &mut ServiceConfig, rate_limit: &RateLimitCell) {
|
|
||||||
cfg.service(
|
|
||||||
web::resource("/api/v3/image_proxy")
|
|
||||||
.wrap(rate_limit.message())
|
|
||||||
.route(web::post().to(image_proxy)),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
struct ImageProxyParams {
|
pub struct ImageProxyParams {
|
||||||
url: String,
|
url: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn image_proxy(
|
pub async fn image_proxy(
|
||||||
Query(params): Query<ImageProxyParams>,
|
Query(params): Query<ImageProxyParams>,
|
||||||
context: web::Data<LemmyContext>,
|
context: web::Data<LemmyContext>,
|
||||||
) -> LemmyResult<HttpResponse> {
|
) -> LemmyResult<HttpResponse> {
|
||||||
|
|
|
@ -65,7 +65,15 @@ pub struct PictrsConfig {
|
||||||
|
|
||||||
/// Cache remote images
|
/// Cache remote images
|
||||||
#[default(true)]
|
#[default(true)]
|
||||||
pub cache_remote_images: bool,
|
pub cache_remote_thumbnails: bool,
|
||||||
|
|
||||||
|
/// If enabled, all images from remote domains are rewritten to pass through `/api/v3/image_proxy`.
|
||||||
|
/// This improves privacy as users don't expose their IP to untrusted servers, and decreases load
|
||||||
|
/// on other servers. However it causes more load for the local server.
|
||||||
|
///
|
||||||
|
/// Requires pict-rs 0.5
|
||||||
|
#[default(false)]
|
||||||
|
pub image_proxy: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Deserialize, Serialize, Clone, SmartDefault, Document)]
|
#[derive(Debug, Deserialize, Serialize, Clone, SmartDefault, Document)]
|
||||||
|
|
|
@ -124,11 +124,17 @@ use lemmy_apub::api::{
|
||||||
search::search,
|
search::search,
|
||||||
user_settings_backup::{export_settings, import_settings},
|
user_settings_backup::{export_settings, import_settings},
|
||||||
};
|
};
|
||||||
|
use lemmy_routes::image_proxy::image_proxy;
|
||||||
use lemmy_utils::rate_limit::RateLimitCell;
|
use lemmy_utils::rate_limit::RateLimitCell;
|
||||||
|
|
||||||
pub fn config(cfg: &mut web::ServiceConfig, rate_limit: &RateLimitCell) {
|
pub fn config(cfg: &mut web::ServiceConfig, rate_limit: &RateLimitCell) {
|
||||||
cfg.service(
|
cfg.service(
|
||||||
web::scope("/api/v3")
|
web::scope("/api/v3")
|
||||||
|
.service(
|
||||||
|
web::scope("")
|
||||||
|
.wrap(rate_limit.message())
|
||||||
|
.route("image_proxy", web::post().to(image_proxy)),
|
||||||
|
)
|
||||||
// Site
|
// Site
|
||||||
.service(
|
.service(
|
||||||
web::scope("/site")
|
web::scope("/site")
|
||||||
|
|
Loading…
Reference in New Issue