diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/database/settings.rs | 19 | ||||
-rw-r--r-- | src/frontend/mod.rs | 22 | ||||
-rw-r--r-- | src/frontend/onboarding.rs | 2 | ||||
-rw-r--r-- | src/indieauth/mod.rs | 15 | ||||
-rw-r--r-- | src/login.rs | 28 |
5 files changed, 72 insertions, 14 deletions
diff --git a/src/database/settings.rs b/src/database/settings.rs index 792a155..77e5821 100644 --- a/src/database/settings.rs +++ b/src/database/settings.rs @@ -1,3 +1,5 @@ +pub use kittybox_frontend_renderer::themes::ThemeName; + mod private { pub trait Sealed {} } @@ -61,3 +63,20 @@ impl Setting for Webring { Self(data) } } + +#[derive(Debug, Default, serde::Serialize, serde::Deserialize, Clone, Copy, PartialEq, Eq)] +/// Theme setting for Kittybox, specifying the stylesheet used for laying out the website. +pub struct Theme(ThemeName); +impl private::Sealed for Theme {} +impl Setting for Theme { + type Data = ThemeName; + const ID: &'static str = "theme"; + + fn into_inner(self) -> Self::Data { + self.0 + } + + fn new(data: Self::Data) -> Self { + Self(data) + } +} diff --git a/src/frontend/mod.rs b/src/frontend/mod.rs index 94b8aa7..a05c91d 100644 --- a/src/frontend/mod.rs +++ b/src/frontend/mod.rs @@ -1,4 +1,4 @@ -use crate::database::{Storage, StorageError}; +use crate::database::{settings::Setting, Storage, StorageError}; use axum::{ extract::{Query, State}, http::{StatusCode, Uri}, @@ -271,11 +271,13 @@ pub async fn homepage<D: Storage>( // other requests anyway if it's serious...) // // btw is it more efficient to fetch these in parallel? - let (blogname, webring, channels) = tokio::join!( + let (blogname, webring, theme, channels) = tokio::join!( db.get_setting::<crate::database::settings::SiteName>(&hcard_url) .map(Result::unwrap_or_default), db.get_setting::<crate::database::settings::Webring>(&hcard_url) .map(Result::unwrap_or_default), + db.get_setting::<crate::database::settings::Theme>(&hcard_url) + .map(Result::unwrap_or_default), db.get_channels(&hcard_url).map(|i| i.unwrap_or_default()) ); @@ -293,6 +295,7 @@ pub async fn homepage<D: Storage>( title: blogname.as_ref(), blog_name: blogname.as_ref(), feeds: channels, + theme: theme.into_inner(), user: session.as_deref(), content: MainPage { feed: &hfeed, @@ -319,9 +322,11 @@ pub async fn homepage<D: Storage>( } else { error!("Error while fetching h-card and/or h-feed: {}", err); // Return the error - let (blogname, channels) = tokio::join!( + let (blogname, theme, channels) = tokio::join!( db.get_setting::<crate::database::settings::SiteName>(&hcard_url) .map(Result::unwrap_or_default), + db.get_setting::<crate::database::settings::Theme>(&hcard_url) + .map(Result::unwrap_or_default), db.get_channels(&hcard_url).map(|i| i.unwrap_or_default()) ); @@ -332,6 +337,7 @@ pub async fn homepage<D: Storage>( title: blogname.as_ref(), blog_name: blogname.as_ref(), feeds: channels, + theme: theme.into_inner(), user: session.as_deref(), content: ErrorPage { code: err.code(), @@ -361,9 +367,11 @@ pub async fn catchall<D: Storage>( match get_post_from_database(&db, path.as_str(), query.after, user).await { Ok((post, cursor)) => { - let (blogname, channels) = tokio::join!( + let (blogname, theme, channels) = tokio::join!( db.get_setting::<crate::database::settings::SiteName>(&host) .map(Result::unwrap_or_default), + db.get_setting::<crate::database::settings::Theme>(&host) + .map(Result::unwrap_or_default), db.get_channels(&host).map(|i| i.unwrap_or_default()) ); let mut headers = axum::http::HeaderMap::new(); @@ -411,6 +419,7 @@ pub async fn catchall<D: Storage>( title: blogname.as_ref(), blog_name: blogname.as_ref(), feeds: channels, + theme: theme.into_inner(), user: session.as_deref(), content: match post.pointer("/type/0").and_then(|i| i.as_str()) { Some("h-entry") => Entry { @@ -434,9 +443,11 @@ pub async fn catchall<D: Storage>( .into_response() } Err(err) => { - let (blogname, channels) = tokio::join!( + let (blogname, theme, channels) = tokio::join!( db.get_setting::<crate::database::settings::SiteName>(&host) .map(Result::unwrap_or_default), + db.get_setting::<crate::database::settings::Theme>(&host) + .map(Result::unwrap_or_default), db.get_channels(&host).map(|i| i.unwrap_or_default()) ); ( @@ -449,6 +460,7 @@ pub async fn catchall<D: Storage>( title: blogname.as_ref(), blog_name: blogname.as_ref(), feeds: channels, + theme: theme.into_inner(), user: session.as_deref(), content: ErrorPage { code: err.code(), diff --git a/src/frontend/onboarding.rs b/src/frontend/onboarding.rs index 3b53911..3caa458 100644 --- a/src/frontend/onboarding.rs +++ b/src/frontend/onboarding.rs @@ -21,6 +21,7 @@ pub async fn get() -> Html<String> { title: "Kittybox - Onboarding", blog_name: "Kittybox", feeds: vec![], + theme: Default::default(), user: None, content: OnboardingPage {}.to_string(), } @@ -150,6 +151,7 @@ pub async fn post<D: Storage + 'static>( title: "Kittybox - Onboarding", blog_name: "Kittybox", feeds: vec![], + theme: Default::default(), user: None, content: ErrorPage { code: err.code(), diff --git a/src/indieauth/mod.rs b/src/indieauth/mod.rs index 5cdbf05..af49a7f 100644 --- a/src/indieauth/mod.rs +++ b/src/indieauth/mod.rs @@ -1,4 +1,4 @@ -use crate::database::Storage; +use crate::database::{settings::Setting, Storage}; use axum::{ extract::{Form, FromRef, Json, Query, State}, http::StatusCode, @@ -13,6 +13,7 @@ use axum_extra::{ headers::{authorization::Bearer, Authorization, ContentType, HeaderMapExt}, TypedHeader, }; +use futures::FutureExt; use kittybox_indieauth::{ AuthorizationRequest, AuthorizationResponse, ClientMetadata, Error, ErrorKind, GrantRequest, GrantResponse, GrantType, IntrospectionEndpointAuthMethod, Metadata, PKCEMethod, Profile, @@ -319,12 +320,20 @@ async fn authorization_endpoint_get<A: AuthBackend, D: Storage + 'static>( { request.scope.replace(Scopes::new(vec![Scope::Profile])); } + let (blog_name, theme, channels) = tokio::join!( + db.get_setting::<crate::database::settings::SiteName>(&me) + .map(Result::unwrap_or_default), + db.get_setting::<crate::database::settings::Theme>(&me) + .map(Result::unwrap_or_default), + db.get_channels(&me).map(|i| i.unwrap_or_default()) + ); Html( kittybox_frontend_renderer::Template { title: "Confirm sign-in via IndieAuth", - blog_name: "Kittybox", - feeds: vec![], + blog_name: &blog_name.as_ref(), + feeds: channels, + theme: theme.into_inner(), user: None, content: kittybox_frontend_renderer::AuthorizationRequestPage { request, diff --git a/src/login.rs b/src/login.rs index 3038d9c..1b6a6f3 100644 --- a/src/login.rs +++ b/src/login.rs @@ -23,7 +23,7 @@ use kittybox_frontend_renderer::{LoginPage, LogoutPage, Template}; use kittybox_indieauth::{AuthorizationResponse, Error, GrantType, PKCEVerifier, Scope, Scopes}; use sha2::Digest; -use crate::database::Storage; +use crate::database::{settings::Setting, Storage}; /// Show a login page. async fn get<S: Storage + Send + Sync + 'static>( @@ -32,9 +32,11 @@ async fn get<S: Storage + Send + Sync + 'static>( ) -> impl axum::response::IntoResponse { let hcard_url: url::Url = format!("https://{}/", host).parse().unwrap(); - let (blogname, channels) = tokio::join!( + let (blogname, theme, channels) = tokio::join!( db.get_setting::<crate::database::settings::SiteName>(&hcard_url) .map(Result::unwrap_or_default), + db.get_setting::<crate::database::settings::Theme>(&hcard_url) + .map(Result::unwrap_or_default), db.get_channels(&hcard_url).map(|i| i.unwrap_or_default()) ); ( @@ -47,6 +49,7 @@ async fn get<S: Storage + Send + Sync + 'static>( title: "Sign in with your website", blog_name: blogname.as_ref(), feeds: channels, + theme: theme.into_inner(), user: None, content: LoginPage {}.to_string(), } @@ -380,14 +383,27 @@ async fn callback( /// of crawlers working with a user's cookies (wget?). If a crawler is /// stupid enough to execute JS and send a POST request though, that's /// on the crawler. -async fn logout_page() -> impl axum::response::IntoResponse { +async fn logout_page<D: Storage + 'static>( + State(db): State<D>, + Host(host): Host, +) -> impl axum::response::IntoResponse { + let me: url::Url = format!("https://{host}/").parse().unwrap(); + let (blog_name, theme, channels) = tokio::join!( + db.get_setting::<crate::database::settings::SiteName>(&me) + .map(Result::unwrap_or_default), + db.get_setting::<crate::database::settings::Theme>(&me) + .map(Result::unwrap_or_default), + db.get_channels(&me).map(|i| i.unwrap_or_default()) + ); + ( StatusCode::OK, [("Content-Type", "text/html")], Template { title: "Signing out...", - blog_name: "Kittybox", - feeds: vec![], + blog_name: blog_name.as_ref(), + theme: theme.into_inner(), + feeds: channels, user: None, content: LogoutPage {}.to_string(), } @@ -501,6 +517,6 @@ where axum::routing::Router::new() .route("/start", axum::routing::get(get::<S>).post(post)) .route("/finish", axum::routing::get(callback)) - .route("/logout", axum::routing::get(logout_page).post(logout)) + .route("/logout", axum::routing::get(logout_page::<S>).post(logout)) .route("/client_metadata", axum::routing::get(client_metadata::<S>)) } |