From 226c3facaa22a5799eb28cf5916c3bde35a063d1 Mon Sep 17 00:00:00 2001 From: Felix Ableitner Date: Thu, 14 Nov 2024 11:07:23 +0100 Subject: [PATCH] Make auth token available during hydrate --- src/backend/mod.rs | 31 +++++++++++++++++++++++++++---- src/common/mod.rs | 3 +++ src/frontend/api.rs | 12 ++++++++++++ 3 files changed, 42 insertions(+), 4 deletions(-) diff --git a/src/backend/mod.rs b/src/backend/mod.rs index 6a6e19a..bf4eada 100644 --- a/src/backend/mod.rs +++ b/src/backend/mod.rs @@ -8,6 +8,7 @@ use crate::{ }, common::{ utils::http_protocol_str, + Auth, DbArticle, DbInstance, DbPerson, @@ -21,16 +22,19 @@ use activitypub_federation::{ fetch::object_id::ObjectId, http_signatures::generate_actor_keypair, }; -use api::api_routes; +use api::{api_routes, user::AUTH_COOKIE}; use assets::file_and_error_handler; use axum::{ body::Body, + extract::State, http::{HeaderValue, Request}, middleware::Next, - response::Response, + response::{IntoResponse, Response}, + routing::get, Router, ServiceExt, }; +use axum_extra::extract::CookieJar; use axum_macros::debug_middleware; use chrono::Utc; use diesel::{ @@ -42,7 +46,7 @@ use federation::objects::{ articles_collection::local_articles_url, instance_collection::linked_instances_url, }; -use leptos::get_configuration; +use leptos::*; use leptos_axum::{generate_route_list, LeptosRoutes}; use log::info; use std::net::SocketAddr; @@ -97,7 +101,8 @@ pub async fn start(config: IbisConfig, override_hostname: Option) -> let config = data.clone(); let app = Router::new() - .leptos_routes(&leptos_options, routes, App) + //.leptos_routes(&leptos_options, routes, App) + .leptos_routes_with_handler(routes, get(leptos_routes_handler)) .fallback(file_and_error_handler) .with_state(leptos_options) .nest(FEDERATION_ROUTES_PREFIX, federation_routes()) @@ -118,6 +123,24 @@ pub async fn start(config: IbisConfig, override_hostname: Option) -> Ok(()) } +/// Make auth token available in hydrate mode +async fn leptos_routes_handler( + jar: CookieJar, + State(option): State, + req: Request, +) -> Response { + let handler = leptos_axum::render_app_async_with_context( + option.clone(), + move || { + let cookie = jar.get(AUTH_COOKIE).map(|c| c.value().to_string()); + provide_context(Auth(cookie)); + }, + move || view! { }, + ); + + handler(req).await.into_response() +} + const MAIN_PAGE_DEFAULT_TEXT: &str = "Welcome to Ibis, the federated Wikipedia alternative! This main page can only be edited by the admin. Use it as an introduction for new users, \ diff --git a/src/common/mod.rs b/src/common/mod.rs index 44bc823..e9f0aa4 100644 --- a/src/common/mod.rs +++ b/src/common/mod.rs @@ -21,6 +21,9 @@ use { pub const MAIN_PAGE_NAME: &str = "Main_Page"; +#[derive(Clone)] +pub struct Auth(pub Option); + /// Should be an enum Title/Id but fails due to https://github.com/nox/serde_urlencoded/issues/66 #[derive(Deserialize, Serialize, Clone, Debug, Default)] pub struct GetArticleForm { diff --git a/src/frontend/api.rs b/src/frontend/api.rs index 73ad047..401795d 100644 --- a/src/frontend/api.rs +++ b/src/frontend/api.rs @@ -267,6 +267,18 @@ where { req = req.fetch_credentials_include(); } + + #[cfg(feature = "ssr")] + { + use crate::common::Auth; + use leptos::use_context; + use reqwest::header::HeaderName; + + let auth = use_context::(); + if let Some(Auth(Some(auth))) = auth { + req = req.header(HeaderName::from_static("auth"), auth); + } + } let res = req.send().await?; let status = res.status(); let text = res.text().await?;