Merge pull request 'Fix browser console warning' (#1) from mrtsunami/motifs:master into master

Reviewed-on: #1
Reviewed-by: mb <matthieu@imagevo.fr>
This commit is contained in:
mb 2024-07-25 18:34:59 +02:00
commit 86ffc13319
4 changed files with 199 additions and 21 deletions

167
Cargo.lock generated
View file

@ -17,6 +17,15 @@ version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
[[package]]
name = "aho-corasick"
version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
dependencies = [
"memchr",
]
[[package]]
name = "android-tzdata"
version = "0.1.1"
@ -205,6 +214,41 @@ version = "0.8.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80"
[[package]]
name = "darling"
version = "0.20.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989"
dependencies = [
"darling_core",
"darling_macro",
]
[[package]]
name = "darling_core"
version = "0.20.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95133861a8032aaea082871032f5815eb9e98cef03fa916ab4500513994df9e5"
dependencies = [
"fnv",
"ident_case",
"proc-macro2",
"quote",
"strsim",
"syn 2.0.72",
]
[[package]]
name = "darling_macro"
version = "0.20.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806"
dependencies = [
"darling_core",
"quote",
"syn 2.0.72",
]
[[package]]
name = "either"
version = "1.13.0"
@ -399,6 +443,22 @@ dependencies = [
"cc",
]
[[package]]
name = "ident_case"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
[[package]]
name = "idna"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6"
dependencies = [
"unicode-bidi",
"unicode-normalization",
]
[[package]]
name = "instant"
version = "0.1.13"
@ -549,6 +609,7 @@ dependencies = [
"sled",
"stylist",
"tokio",
"validator",
]
[[package]]
@ -699,6 +760,35 @@ dependencies = [
"bitflags",
]
[[package]]
name = "regex"
version = "1.10.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f"
dependencies = [
"aho-corasick",
"memchr",
"regex-automata",
"regex-syntax",
]
[[package]]
name = "regex-automata"
version = "0.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax",
]
[[package]]
name = "regex-syntax"
version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b"
[[package]]
name = "rustc-demangle"
version = "0.1.24"
@ -819,6 +909,12 @@ dependencies = [
"windows-sys",
]
[[package]]
name = "strsim"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
[[package]]
name = "stylist"
version = "0.13.0"
@ -924,6 +1020,21 @@ dependencies = [
"syn 2.0.72",
]
[[package]]
name = "tinyvec"
version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938"
dependencies = [
"tinyvec_macros",
]
[[package]]
name = "tinyvec_macros"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
[[package]]
name = "tokio"
version = "1.39.1"
@ -998,12 +1109,68 @@ dependencies = [
"once_cell",
]
[[package]]
name = "unicode-bidi"
version = "0.3.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75"
[[package]]
name = "unicode-ident"
version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
[[package]]
name = "unicode-normalization"
version = "0.1.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5"
dependencies = [
"tinyvec",
]
[[package]]
name = "url"
version = "2.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c"
dependencies = [
"form_urlencoded",
"idna",
"percent-encoding",
]
[[package]]
name = "validator"
version = "0.18.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "db79c75af171630a3148bd3e6d7c4f42b6a9a014c2945bc5ed0020cbb8d9478e"
dependencies = [
"idna",
"once_cell",
"regex",
"serde",
"serde_derive",
"serde_json",
"url",
"validator_derive",
]
[[package]]
name = "validator_derive"
version = "0.18.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "55591299b7007f551ed1eb79a684af7672c19c3193fb9e0a31936987bb2438ec"
dependencies = [
"darling",
"once_cell",
"proc-macro-error",
"proc-macro2",
"quote",
"syn 2.0.72",
]
[[package]]
name = "version_check"
version = "0.9.4"

View file

@ -14,3 +14,4 @@ serde_json = "1.0.120"
sled = "0.34.7"
stylist = "0.13.0"
tokio = { version = "1.39.1", features = ["net", "rt-multi-thread"] }
validator = { version = "0.18.1", features = ["derive"] }

View file

@ -88,5 +88,5 @@ pub async fn style() -> impl IntoResponse {
.get_style_str()
.to_string();
([("content-type", "style/css")], style)
([("content-type", "text/css")], style)
}

View file

@ -13,10 +13,11 @@ use axum::{
};
use chrono::prelude::*;
use common::{footer, head, header, style};
use maud::{html, Escaper, Markup, PreEscaped};
use maud::{html, Escaper, Markup, PreEscaped, DOCTYPE};
use serde::{Deserialize, Serialize};
use store::Store;
use tokio::net::TcpListener;
use validator::{Validate, ValidationError};
mod common;
mod store;
@ -50,6 +51,7 @@ async fn main() -> Result<()> {
async fn home() -> Markup {
html!(
(DOCTYPE)
(head(""))
body {
content {
@ -71,6 +73,7 @@ async fn home() -> Markup {
async fn topics(State(state): State<MainState>) -> impl IntoResponse {
let topics = state.store.read().unwrap().list().unwrap();
html!(
(DOCTYPE)
(head("sujets"))
body {
content {
@ -94,6 +97,7 @@ async fn topics(State(state): State<MainState>) -> impl IntoResponse {
async fn activity(State(state): State<MainState>) -> impl IntoResponse {
let topics = state.store.read().unwrap().activity().unwrap();
html!(
(DOCTYPE)
(head("activité"))
body {
content {
@ -120,6 +124,7 @@ async fn topic(Path(name): Path<String>, State(state): State<MainState>) -> impl
};
html!(
(DOCTYPE)
(head(&name))
body {
content {
@ -142,35 +147,38 @@ async fn topic(Path(name): Path<String>, State(state): State<MainState>) -> impl
)
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[derive(Debug, Clone, Serialize, Deserialize, Validate)]
struct PostContent {
#[validate(length(min = 1, max = 32), custom(function = "validate_topic"))]
topic: String,
#[validate(length(min = 10, max = 10_000))]
content: String,
#[validate(length(min = 2, max = 32))]
author: String,
}
async fn post(
State(state): State<MainState>,
Form(PostContent {
fn validate_topic(topic: &str) -> Result<(), ValidationError> {
if topic.starts_with('_') || topic.ends_with('_') {
return Err(ValidationError::new("Bad topic format."));
}
Ok(())
}
async fn post(State(state): State<MainState>, Form(post_content): Form<PostContent>) -> Response {
let mut store = state.store.write().unwrap();
let date = Utc::now().format("%d/%m/%Y");
if post_content.validate().is_err() {
return (StatusCode::BAD_REQUEST, "Bad input.").into_response();
}
let PostContent {
topic,
content,
author,
}): Form<PostContent>,
) -> Response {
let mut store = state.store.write().unwrap();
let date = Utc::now().format("%d/%m/%Y");
let topic = sanithize_identifier(topic.trim());
let content = content.trim();
} = post_content;
if content.len() < 10 || content.len() > 10_000 {
return (StatusCode::BAD_REQUEST, "Bad content.").into_response();
}
if author.len() > 2 || author.len() > 32 {
return (StatusCode::BAD_REQUEST, "Bad author.").into_response();
}
if topic.len() > 32 || topic.is_empty() || topic.starts_with('_') || topic.ends_with('_') {
return (StatusCode::BAD_REQUEST, "Bad topic.").into_response();
}
let topic = sanithize_identifier(&topic);
let content = format!("{content}\n\t~{author}, {date}");
store.insert(&topic, content).unwrap();
@ -210,6 +218,7 @@ fn sanithize_identifier(input: &str) -> String {
async fn create() -> impl IntoResponse {
html!(
(DOCTYPE)
(head("créer"))
body {
content {
@ -242,6 +251,7 @@ async fn create() -> impl IntoResponse {
fn error(message: impl ToString) -> Markup {
let message = message.to_string();
html!(
(DOCTYPE)
(head("Failure"))
body {
content {