2024-05-11 22:47:29 +02:00
|
|
|
#[serde_inline_default::serde_inline_default]
|
|
|
|
#[derive(Debug, Clone, serde::Deserialize, serde::Serialize, serde_default::DefaultFromSerde)]
|
|
|
|
pub struct Config {
|
|
|
|
#[serde(default)]
|
|
|
|
pub instance: InstanceConfig,
|
|
|
|
|
|
|
|
#[serde(default)]
|
|
|
|
pub datasource: DatasourceConfig,
|
|
|
|
|
2024-05-13 18:53:51 +02:00
|
|
|
#[serde(default)]
|
|
|
|
pub security: SecurityConfig,
|
|
|
|
|
2024-08-11 12:48:46 +02:00
|
|
|
#[serde(default)]
|
|
|
|
pub compat: CompatibilityConfig,
|
|
|
|
|
2024-11-09 14:41:19 +01:00
|
|
|
#[serde(default)]
|
|
|
|
pub files: FileStorageConfig,
|
|
|
|
|
2024-12-29 03:25:10 +01:00
|
|
|
#[serde(default)]
|
|
|
|
pub reject: RejectConfig,
|
|
|
|
|
2024-05-11 22:47:29 +02:00
|
|
|
// TODO should i move app keys here?
|
|
|
|
}
|
|
|
|
|
2024-05-13 18:53:51 +02:00
|
|
|
#[serde_inline_default::serde_inline_default]
|
|
|
|
#[derive(Debug, Clone, serde::Deserialize, serde::Serialize, serde_default::DefaultFromSerde)]
|
|
|
|
pub struct InstanceConfig {
|
|
|
|
#[serde_inline_default("μpub".into())]
|
2024-12-29 04:34:34 +01:00
|
|
|
/// instance name, shown in noedinfo and instance actor
|
2024-05-13 18:53:51 +02:00
|
|
|
pub name: String,
|
|
|
|
|
|
|
|
#[serde_inline_default("micro social network, federated".into())]
|
2024-12-29 04:34:34 +01:00
|
|
|
/// description, shown in nodeinfo and instance actor
|
2024-05-13 18:53:51 +02:00
|
|
|
pub description: String,
|
|
|
|
|
2025-01-22 02:07:53 +01:00
|
|
|
#[serde_inline_default("http://127.0.0.1:3000".into())]
|
2025-01-22 01:16:22 +01:00
|
|
|
/// domain of current instance, must change this for prod
|
2024-05-13 18:53:51 +02:00
|
|
|
pub domain: String,
|
|
|
|
|
|
|
|
#[serde(default)]
|
2024-12-29 04:34:34 +01:00
|
|
|
/// contact information for an administrator, currently unused
|
2025-01-22 01:16:22 +01:00
|
|
|
pub contact: String,
|
2024-05-13 18:53:51 +02:00
|
|
|
|
|
|
|
#[serde(default)]
|
2024-12-29 04:34:34 +01:00
|
|
|
/// base url for frontend, will be used to compose pretty urls
|
2025-01-22 01:16:22 +01:00
|
|
|
pub frontend: String,
|
2024-05-13 18:53:51 +02:00
|
|
|
}
|
|
|
|
|
2024-05-11 22:47:29 +02:00
|
|
|
#[serde_inline_default::serde_inline_default]
|
|
|
|
#[derive(Debug, Clone, serde::Deserialize, serde::Serialize, serde_default::DefaultFromSerde)]
|
|
|
|
pub struct DatasourceConfig {
|
2025-01-22 01:16:22 +01:00
|
|
|
#[serde_inline_default("sqlite://./upub.db?mode=rwc".into())]
|
2024-05-11 22:47:29 +02:00
|
|
|
pub connection_string: String,
|
|
|
|
|
2024-06-08 17:32:22 +02:00
|
|
|
#[serde_inline_default(32)]
|
2024-05-11 22:47:29 +02:00
|
|
|
pub max_connections: u32,
|
|
|
|
|
|
|
|
#[serde_inline_default(1)]
|
|
|
|
pub min_connections: u32,
|
|
|
|
|
2024-06-08 17:32:22 +02:00
|
|
|
#[serde_inline_default(90u64)]
|
2024-05-11 22:47:29 +02:00
|
|
|
pub connect_timeout_seconds: u64,
|
|
|
|
|
2024-06-08 17:32:22 +02:00
|
|
|
#[serde_inline_default(30u64)]
|
2024-05-11 22:47:29 +02:00
|
|
|
pub acquire_timeout_seconds: u64,
|
|
|
|
|
2024-06-08 17:32:22 +02:00
|
|
|
#[serde_inline_default(10u64)]
|
2024-12-29 04:34:34 +01:00
|
|
|
/// threshold for queries to be considered slow
|
2024-05-11 22:47:29 +02:00
|
|
|
pub slow_query_warn_seconds: u64,
|
|
|
|
|
|
|
|
#[serde_inline_default(true)]
|
2024-12-29 04:34:34 +01:00
|
|
|
/// enable logging warn for slow queries
|
2024-05-11 22:47:29 +02:00
|
|
|
pub slow_query_warn_enable: bool,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[serde_inline_default::serde_inline_default]
|
|
|
|
#[derive(Debug, Clone, serde::Deserialize, serde::Serialize, serde_default::DefaultFromSerde)]
|
2024-05-13 18:53:51 +02:00
|
|
|
pub struct SecurityConfig {
|
2024-05-11 22:47:29 +02:00
|
|
|
#[serde(default)]
|
2024-12-29 04:34:34 +01:00
|
|
|
/// allow new users to register autonomously
|
2024-05-13 18:53:51 +02:00
|
|
|
pub allow_registration: bool,
|
2024-05-20 01:42:30 +02:00
|
|
|
|
2024-06-28 05:13:02 +02:00
|
|
|
#[serde(default)] // TODO i don't like the name of this
|
2024-12-29 04:34:34 +01:00
|
|
|
/// newly registered users require manual activation
|
2024-06-28 05:13:02 +02:00
|
|
|
pub require_user_approval: bool,
|
|
|
|
|
2024-05-20 01:42:30 +02:00
|
|
|
#[serde(default)]
|
2024-12-29 04:34:34 +01:00
|
|
|
/// allow anonymous users access to fetch debugger (explore screen)
|
2024-05-20 01:42:30 +02:00
|
|
|
pub allow_public_debugger: bool,
|
2024-05-24 00:25:41 +02:00
|
|
|
|
2024-08-11 14:46:15 +02:00
|
|
|
#[serde(default)]
|
2024-12-29 04:34:34 +01:00
|
|
|
/// allow anonymous users to perform full-text searches
|
2024-08-11 14:46:15 +02:00
|
|
|
pub allow_public_search: bool,
|
|
|
|
|
2025-01-23 01:41:57 +01:00
|
|
|
#[serde_inline_default(30)]
|
|
|
|
/// max time, in seconds, before requests fail with timeout
|
|
|
|
pub request_timeout: u64,
|
|
|
|
|
2025-01-22 01:16:22 +01:00
|
|
|
#[serde_inline_default("definitely-change-this-in-prod".to_string())]
|
2024-12-29 04:34:34 +01:00
|
|
|
/// secret for media proxy, set this to something random
|
2024-06-23 03:55:03 +02:00
|
|
|
pub proxy_secret: String,
|
|
|
|
|
2024-06-07 02:22:43 +02:00
|
|
|
#[serde_inline_default(true)]
|
2024-12-29 04:34:34 +01:00
|
|
|
/// allow expired tokens to be refreshed
|
2024-05-27 07:26:31 +02:00
|
|
|
pub allow_login_refresh: bool,
|
2024-05-30 23:22:58 +02:00
|
|
|
|
2024-06-07 02:22:43 +02:00
|
|
|
#[serde_inline_default(7 * 24)]
|
2024-12-29 04:34:34 +01:00
|
|
|
/// how long do login sessions last
|
2024-06-07 02:22:43 +02:00
|
|
|
pub session_duration_hours: i64,
|
|
|
|
|
2024-05-30 23:22:58 +02:00
|
|
|
#[serde_inline_default(2)]
|
2024-12-29 04:34:34 +01:00
|
|
|
/// how many times we allow an object to redirect
|
2024-08-11 14:46:15 +02:00
|
|
|
pub max_id_redirects: u32, // TODO not sure it fits here
|
2024-05-30 23:22:58 +02:00
|
|
|
|
|
|
|
#[serde_inline_default(20)]
|
2024-12-29 04:34:34 +01:00
|
|
|
/// how deep should threads be crawled for fetching replies
|
2024-08-11 14:46:15 +02:00
|
|
|
pub thread_crawl_depth: u32, // TODO doesn't really fit here
|
2024-06-06 04:27:49 +02:00
|
|
|
|
|
|
|
#[serde_inline_default(30)]
|
2024-12-29 04:34:34 +01:00
|
|
|
/// how long before a job is considered stale and dropped
|
2024-08-11 14:46:15 +02:00
|
|
|
pub job_expiration_days: u32, // TODO doesn't really fit here
|
2024-06-06 04:36:16 +02:00
|
|
|
|
|
|
|
#[serde_inline_default(100)]
|
2024-12-29 04:34:34 +01:00
|
|
|
/// how many times to attempt inserting back incomplete jobs
|
2024-08-11 14:46:15 +02:00
|
|
|
pub reinsertion_attempt_limit: u32, // TODO doesn't really fit here
|
2024-05-11 22:47:29 +02:00
|
|
|
}
|
|
|
|
|
2024-08-11 12:48:46 +02:00
|
|
|
#[serde_inline_default::serde_inline_default]
|
|
|
|
#[derive(Debug, Clone, serde::Deserialize, serde::Serialize, serde_default::DefaultFromSerde)]
|
|
|
|
pub struct CompatibilityConfig {
|
2025-01-22 01:16:22 +01:00
|
|
|
#[serde_inline_default(true)]
|
2024-12-29 04:34:34 +01:00
|
|
|
/// compatibility with almost everything: set image attachments as images
|
2024-08-11 12:48:46 +02:00
|
|
|
pub fix_attachment_images_media_type: bool,
|
|
|
|
|
2025-01-22 01:16:22 +01:00
|
|
|
#[serde_inline_default(true)]
|
|
|
|
/// compatibility with mastodon and misskey (and somewhat lemmy?): notify like receiver
|
2024-08-11 12:50:50 +02:00
|
|
|
pub add_explicit_target_to_likes_if_local: bool,
|
2024-08-11 17:38:10 +02:00
|
|
|
|
2025-01-22 01:16:22 +01:00
|
|
|
#[serde_inline_default(true)]
|
2024-12-29 04:34:34 +01:00
|
|
|
/// compatibility with lemmy: avoid showing images twice
|
2024-08-11 17:38:10 +02:00
|
|
|
pub skip_single_attachment_if_image_is_set: bool,
|
2025-01-28 13:55:20 +01:00
|
|
|
|
|
|
|
#[serde_inline_default(false)]
|
|
|
|
/// compatibility with most relays: since they send us other server's activities, we must fetch
|
|
|
|
/// them to verify that they aren't falsified by the relay itself. this is quite expensive, as
|
|
|
|
/// relays send a lot of activities and we effectively end up fetching again all these, so this
|
|
|
|
/// defaults to false
|
|
|
|
pub verify_relayed_activities_by_fetching: bool,
|
2024-08-11 12:48:46 +02:00
|
|
|
}
|
2024-05-11 22:47:29 +02:00
|
|
|
|
2024-11-09 14:41:19 +01:00
|
|
|
#[serde_inline_default::serde_inline_default]
|
|
|
|
#[derive(Debug, Clone, serde::Deserialize, serde::Serialize, serde_default::DefaultFromSerde)]
|
|
|
|
pub struct FileStorageConfig {
|
|
|
|
#[serde_inline_default("files/".to_string())]
|
2024-12-29 04:34:34 +01:00
|
|
|
/// path where media files should be stored
|
2024-11-09 14:41:19 +01:00
|
|
|
pub path: String,
|
|
|
|
}
|
|
|
|
|
2024-12-29 03:25:10 +01:00
|
|
|
#[serde_inline_default::serde_inline_default]
|
|
|
|
#[derive(Debug, Clone, serde::Deserialize, serde::Serialize, serde_default::DefaultFromSerde)]
|
|
|
|
pub struct RejectConfig {
|
|
|
|
#[serde(default)]
|
2024-12-29 04:44:50 +01:00
|
|
|
/// discard incoming activities from these instances
|
|
|
|
pub incoming: Vec<String>,
|
2024-12-29 03:25:10 +01:00
|
|
|
|
2024-12-31 17:11:06 +01:00
|
|
|
#[serde(default)]
|
|
|
|
/// prevent fetching content from these instances
|
|
|
|
pub fetch: Vec<String>,
|
|
|
|
|
2024-12-31 16:29:34 +01:00
|
|
|
#[serde(default)]
|
|
|
|
/// prevent content from these instances from being displayed publicly
|
|
|
|
/// this effectively removes the public (aka NULL) addressing: only other addressees (followers,
|
|
|
|
/// mentions) will be able to see content from these instances on timelines and directly
|
|
|
|
pub public: Vec<String>,
|
|
|
|
|
2024-12-29 03:25:10 +01:00
|
|
|
#[serde(default)]
|
2024-12-29 04:34:34 +01:00
|
|
|
/// prevent proxying media coming from these instances
|
2024-12-29 03:25:10 +01:00
|
|
|
pub media: Vec<String>,
|
|
|
|
|
|
|
|
#[serde(default)]
|
2024-12-29 04:34:34 +01:00
|
|
|
/// skip delivering to these instances
|
2024-12-29 03:25:10 +01:00
|
|
|
pub delivery: Vec<String>,
|
2024-12-29 03:31:59 +01:00
|
|
|
|
|
|
|
#[serde(default)]
|
2024-12-29 04:34:34 +01:00
|
|
|
/// prevent fetching private content from these instances
|
2024-12-29 03:31:59 +01:00
|
|
|
pub access: Vec<String>,
|
2024-12-31 16:30:45 +01:00
|
|
|
|
|
|
|
#[serde(default)]
|
|
|
|
/// reject any request from these instances (ineffective as they can still fetch anonymously)
|
|
|
|
pub requests: Vec<String>,
|
2024-12-29 03:25:10 +01:00
|
|
|
}
|
|
|
|
|
2024-05-11 22:47:29 +02:00
|
|
|
impl Config {
|
2024-06-14 15:51:55 +02:00
|
|
|
pub fn load(path: Option<&std::path::PathBuf>) -> Self {
|
2024-05-11 22:47:29 +02:00
|
|
|
let Some(cfg_path) = path else { return Config::default() };
|
|
|
|
match std::fs::read_to_string(cfg_path) {
|
|
|
|
Ok(x) => match toml::from_str(&x) {
|
|
|
|
Ok(cfg) => return cfg,
|
|
|
|
Err(e) => tracing::error!("failed parsing config file: {e}"),
|
|
|
|
},
|
|
|
|
Err(e) => tracing::error!("failed reading config file: {e}"),
|
|
|
|
}
|
|
|
|
Config::default()
|
|
|
|
}
|
2024-06-06 02:14:35 +02:00
|
|
|
|
2025-01-22 01:16:22 +01:00
|
|
|
// TODO this is very magic... can we do better? maybe formalize frontend url as an attribute of
|
|
|
|
// our application?
|
2024-06-06 02:14:35 +02:00
|
|
|
pub fn frontend_url(&self, url: &str) -> Option<String> {
|
2025-01-22 01:16:22 +01:00
|
|
|
if !self.instance.frontend.is_empty() {
|
|
|
|
Some(format!("{}{url}", self.instance.frontend))
|
|
|
|
} else {
|
|
|
|
None
|
|
|
|
}
|
2024-06-06 02:14:35 +02:00
|
|
|
}
|
2024-05-11 22:47:29 +02:00
|
|
|
}
|