From 15b417c6d62728a9d84d01425ea6f44983f16e64 Mon Sep 17 00:00:00 2001 From: trisua Date: Sat, 2 Aug 2025 01:30:11 -0400 Subject: [PATCH] add: safety_content_warning, master_pass env var --- Cargo.lock | 46 +++++++++++++++++----------- Cargo.toml | 6 ++-- README.md | 2 ++ app/public/fluffle_bunny.webp | Bin 0 -> 22440 bytes app/public/style.css | 6 +++- app/templates_src/view.lisp | 8 +++++ app/templates_src/warning.lisp | 54 +++++++++++++++++++++++++++++++++ src/model.rs | 19 ++++++++++++ src/routes.rs | 38 ++++++++++++++++++----- 9 files changed, 150 insertions(+), 29 deletions(-) create mode 100644 app/public/fluffle_bunny.webp create mode 100644 app/templates_src/warning.lisp diff --git a/Cargo.lock b/Cargo.lock index 3262e0a..b05f860 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -571,7 +571,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "778e2ac28f6c47af28e4907f13ffd1e1ddbd400980a9abd7c8df189bf578a5ad" dependencies = [ "libc", - "windows-sys 0.59.0", + "windows-sys 0.52.0", ] [[package]] @@ -623,7 +623,7 @@ dependencies = [ "tetratto-core", "tetratto-shared", "tokio", - "toml 0.9.2", + "toml 0.9.4", "tower-http", "tracing", "tracing-subscriber", @@ -997,7 +997,7 @@ dependencies = [ "libc", "percent-encoding", "pin-project-lite", - "socket2", + "socket2 0.5.10", "system-configuration", "tokio", "tower-service", @@ -1951,7 +1951,7 @@ dependencies = [ "pin-project-lite", "ryu", "sha1_smol", - "socket2", + "socket2 0.5.10", "tokio", "tokio-util", "url", @@ -2082,7 +2082,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys", - "windows-sys 0.59.0", + "windows-sys 0.52.0", ] [[package]] @@ -2205,9 +2205,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.141" +version = "1.0.142" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30b9eff21ebe718216c6ec64e1d9ac57087aad11efc64e32002bce4a0d4c03d3" +checksum = "030fedb782600dcbd6f02d479bf0d817ac3bb40d644745b769d6a96bc3afc5a7" dependencies = [ "itoa", "memchr", @@ -2397,6 +2397,16 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "socket2" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "233504af464074f9d066d7b5416c5f9b894a5862a6506e306f7b816cdd6f1807" +dependencies = [ + "libc", + "windows-sys 0.59.0", +] + [[package]] name = "stable_deref_trait" version = "1.2.0" @@ -2513,7 +2523,7 @@ dependencies = [ "getrandom 0.3.3", "once_cell", "rustix", - "windows-sys 0.59.0", + "windows-sys 0.52.0", ] [[package]] @@ -2571,7 +2581,7 @@ dependencies = [ "tetratto-l10n", "tetratto-shared", "tokio", - "toml 0.9.2", + "toml 0.9.4", "totp-rs", ] @@ -2583,7 +2593,7 @@ checksum = "d96f5e41633c757e3519efb47c9b85d00d14322c1961360e126d0ecc0ea79b86" dependencies = [ "pathbufd", "serde", - "toml 0.9.2", + "toml 0.9.4", ] [[package]] @@ -2711,9 +2721,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.46.1" +version = "1.47.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cc3a2344dafbe23a245241fe8b09735b521110d30fcefbbd5feb1797ca35d17" +checksum = "89e49afdadebb872d3145a5638b59eb0691ea23e46ca484037cfab3b76b95038" dependencies = [ "backtrace", "bytes", @@ -2723,9 +2733,9 @@ dependencies = [ "parking_lot", "pin-project-lite", "slab", - "socket2", + "socket2 0.6.0", "tokio-macros", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -2769,7 +2779,7 @@ dependencies = [ "postgres-protocol", "postgres-types", "rand 0.9.1", - "socket2", + "socket2 0.5.10", "tokio", "tokio-util", "whoami", @@ -2824,9 +2834,9 @@ dependencies = [ [[package]] name = "toml" -version = "0.9.2" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed0aee96c12fa71097902e0bb061a5e1ebd766a6636bb605ba401c45c1650eac" +checksum = "41ae868b5a0f67631c14589f7e250c1ea2c574ee5ba21c6c8dd4b1485705a5a1" dependencies = [ "indexmap", "serde", @@ -3385,7 +3395,7 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "windows-sys 0.59.0", + "windows-sys 0.52.0", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 030acff..ad1dcb9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,7 +10,7 @@ homepage = "https://fluffle.cc" [dependencies] tetratto-core = "12.0.2" tetratto-shared = "12.0.6" -tokio = { version = "1.46.1", features = ["macros", "rt-multi-thread"] } +tokio = { version = "1.47.1", features = ["macros", "rt-multi-thread"] } pathbufd = "0.1.4" serde = { version = "1.0.219", features = ["derive"] } tera = "1.20.0" @@ -27,7 +27,7 @@ axum-extra = { version = "0.10.1", features = ["cookie"] } nanoneo = "0.2.0" dotenv = "0.15.0" glob = "0.3.2" -serde_json = "1.0.141" -toml = "0.9.2" +serde_json = "1.0.142" +toml = "0.9.4" serde_valid = { version = "1.0.5", features = ["toml"] } regex = "1.11.1" diff --git a/README.md b/README.md index f21eea0..0e72c79 100644 --- a/README.md +++ b/README.md @@ -38,6 +38,8 @@ Once you've built the binary, it'll be located at (from the root `fluffle/` dire All templates are compiled with [nanoneo](https://trisua.com/t/nanoneo), so it's recommended that you familiarize yourself with that syntax. +You can set a master password to be able to freely edit all entries by using the `MASTER_PASS` environment variable. + ## Attribution Fluffle is licensed under the AGPL-3.0 license. Tetratto is also licensed under the AGPL-3.0 license. diff --git a/app/public/fluffle_bunny.webp b/app/public/fluffle_bunny.webp new file mode 100644 index 0000000000000000000000000000000000000000..41f20ea4e7db555cd65c0772a90e5af66d864daa GIT binary patch literal 22440 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 { + toggle_metadata_css({ target: document.getElementById(\"toggle_high_contrast_button\") }); + }, 150);")) +(text "{%- endif %}") (text "{% endblock %}") diff --git a/app/templates_src/warning.lisp b/app/templates_src/warning.lisp new file mode 100644 index 0000000..62bc611 --- /dev/null +++ b/app/templates_src/warning.lisp @@ -0,0 +1,54 @@ +(text "{% extends \"root.lisp\" %} {% block head %}") +(text "{% if not metadata.page_title -%}") +(title + (text "{{ entry.slug }}")) +(text "{%- endif %} {{ metadata_head|safe }}") + +(text "{% if not metadata.share_title -%}") +(meta ("property" "og:title") ("content" "{{ entry.slug }}")) +(meta ("property" "twitter:title") ("content" "{{ entry.slug }}")) +(text "{%- endif %}") + +(text "{% if metadata.page_icon|length == 0 -%}") +(link ("rel" "icon") ("href" "/public/favicon.svg")) +(text "{%- endif %}") + +(text "{% endblock %} {% block body %}") +(div + ("class" "card container flex flex-col gap-1") + ("id" "content_rect") + (p ("class" "fade") (text "Content warning:")) + (div (text "{{ metadata.safety_content_warning|markdown|safe }}")) + (hr) + (div + ("class" "flex flex-col gap-4") + (label + ("class" "flex flex-row gap-2 items-center") + ("for" "open_in_high_contrast") + (input + ("type" "checkbox") + ("id" "open_in_high_contrast") + ("name" "open_in_high_contrast")) + (span (text "Open in high contrast"))) + (div + ("class" "flex gap-2") + (button + ("class" "button surface green") + ("onclick" "accept()") + (text "Continue")) + (button + ("class" "button surface red") + ("onclick" "window.history.back()") + (text "Cancel"))))) + +(script + (text "const QFLAGS = [\"AcceptWarning\"]; + function accept() { + if (document.getElementById(\"open_in_high_contrast\").checked) { + QFLAGS.push(\"EntryHighContrast\"); + } + + document.cookie = `Atto-QFlags=\"${JSON.stringify(QFLAGS)}\"; path=/`; + window.location.reload(); + }")) +(text "{% endblock %}") diff --git a/src/model.rs b/src/model.rs index 58b90fc..ad8a348 100644 --- a/src/model.rs +++ b/src/model.rs @@ -342,6 +342,7 @@ pub struct EntryMetadata { pub content_font_weight: u32, /// The text size of elements (separated by space). #[serde(default, alias = "CONTENT_TEXT_SIZE")] + #[validate(max_length = 128)] pub content_text_size: String, /// The text size of elements by element tag. /// @@ -357,13 +358,19 @@ pub struct EntryMetadata { pub content_text_align: TextAlignment, /// The base text color. #[serde(default, alias = "CONTENT_TEXT_COLOR")] + #[validate(max_length = 128)] pub content_text_color: String, /// The color of links. #[serde(default, alias = "CONTENT_LINK_COLOR")] + #[validate(max_length = 128)] pub content_link_color: String, /// If paragraph elements have a margin below them. #[serde(default, alias = "CONTENT_DISABLE_PARAGRAPH_MARGIN")] pub content_disable_paragraph_margin: bool, + /// The content warning shown before viewing this entry. + #[serde(default, alias = "SAFETY_CONTENT_WARNING")] + #[validate(max_length = 512)] + pub safety_content_warning: String, } macro_rules! metadata_css { @@ -684,3 +691,15 @@ impl EntryMetadata { output } } + +/// Flags that can be provided through the "Atto-QFlags" cookie to customize the +/// resulting page. +#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)] +pub enum QuickFlag { + /// If the entry's warning is automatically skipped. + AcceptWarning, + /// If the entry is automatically set to high-contrast mode. + EntryHighContrast, +} + +pub type QuickFlags = Vec; diff --git a/src/routes.rs b/src/routes.rs index 650476d..64029f6 100644 --- a/src/routes.rs +++ b/src/routes.rs @@ -2,7 +2,7 @@ use std::env::var; use crate::{ State, - model::{Entry, EntryMetadata}, + model::{Entry, EntryMetadata, QuickFlag, QuickFlags}, }; use axum::{ Extension, Json, Router, @@ -126,11 +126,20 @@ pub struct ViewQuery { } async fn view_request( + jar: CookieJar, Extension(data): Extension, Path(mut slug): Path, Query(props): Query, ) -> impl IntoResponse { let (ref data, ref tera, ref build_code) = *data.read().await; + let qflags: QuickFlags = match jar.get("Atto-QFlags") { + Some(x) => match serde_json::from_str(&x.value_trimmed()) { + Ok(x) => x, + Err(_) => QuickFlags::default(), + }, + None => QuickFlags::default(), + }; + slug = slug.to_lowercase(); let entry = match data @@ -222,8 +231,15 @@ async fn view_request( ctx.insert("metadata_head", &metadata.head_tags()); ctx.insert("metadata_css", &metadata.css()); ctx.insert("password", &props.key); + ctx.insert("flags", &qflags); - Html(tera.render("view.lisp", &ctx).unwrap()) + if metadata.safety_content_warning.is_empty() | qflags.contains(&QuickFlag::AcceptWarning) { + // regular view + Html(tera.render("view.lisp", &ctx).unwrap()) + } else { + // warning + Html(tera.render("warning.lisp", &ctx).unwrap()) + } } async fn editor_request( @@ -614,12 +630,20 @@ async fn edit_request( let using_modify_code = edit_code == entry.modify_code; // check edit code - if edit_code - != *if using_modify_code { - &entry.modify_code - } else { - &entry.edit_code + let mut using_master = false; + if let Ok(master_pass) = var("MASTER_PASS") { + if req.edit_code == master_pass { + using_master = true; } + } + + if !using_master + && edit_code + != *if using_modify_code { + &entry.modify_code + } else { + &entry.edit_code + } { return Json(Error::NotAllowed.into()); }