tallyweb_frontend/
session.rs

1#![allow(unused_braces)]
2use super::*;
3use leptos::*;
4use serde::{Deserialize, Serialize};
5
6#[server]
7pub async fn actix_extract_user() -> Result<UserSession, ServerFnError> {
8    use super::AppError;
9    use leptos_actix::{extract, redirect};
10
11    let header = extract::<actix_web::HttpRequest>().await?;
12    match header.cookie("session") {
13        Some(session) => return Ok(serde_json::from_str(&session.value().to_string())?),
14
15        None => {
16            redirect("/login");
17            return Err(AppError::MissingSession)?;
18        }
19    };
20}
21
22async fn get_user_signal() -> RwSignal<UserSession> {
23    match actix_extract_user().await {
24        Ok(session) => session.into(),
25
26        Err(err) => {
27            eprintln!("{err}");
28            UserSession::default().into()
29        }
30    }
31}
32
33#[derive(Debug, Default, Clone, PartialEq, Serialize, Deserialize)]
34pub struct UserSession {
35    pub user_uuid: uuid::Uuid,
36    pub username: String,
37    pub token: uuid::Uuid,
38}
39
40#[component(transparent)]
41pub fn SessionFormInput(#[prop(into)] session: MaybeSignal<UserSession>) -> impl IntoView {
42    let session_val = store_value(session);
43    view! {
44        <input
45            type="hidden"
46            name="session_user_uuid"
47            value=move || session_val()().user_uuid.to_string()
48        />
49        <input type="hidden" name="session_username" value=move || session_val()().username />
50        <input type="hidden" name="session_token" value=move || session_val()().token.to_string() />
51    }
52}
53
54#[component(transparent)]
55pub fn ProvideSessionSignal(children: ChildrenFn) -> impl IntoView {
56    view! {
57        <Await future=get_user_signal let:user>
58
59            {
60                create_blocking_resource(*user, move |u| { api::check_user(u) });
61                provide_context(*user);
62                children()
63            }
64
65        </Await>
66    }
67}