1use leptos::prelude::*;
2use reqwest::Method;
3use crate::{components::AuthResponse, URL_BASE};
4
5#[derive(Debug, Clone, Copy)]
6pub struct Auth {
7 pub token: Signal<Option<String>>,
8 pub userid: Signal<Option<String>>,
9}
10
11impl Auth {
12 pub fn token(&self) -> String {
13 self.token.get().unwrap_or_default()
14 }
15
16 pub fn user_id(&self) -> String {
17 self.userid.get().unwrap_or_default()
18 }
19
20 pub fn username(&self) -> String {
21 self.userid.get()
23 .unwrap_or_default()
24 .split('/')
25 .next_back()
26 .unwrap_or_default()
27 .to_string()
28 }
29
30 pub fn present(&self) -> bool {
31 self.token.get().is_some_and(|x| !x.is_empty())
32 }
33
34 pub fn anonymous(&self) -> bool {
35 self.token.get().is_none_or(|x| x.is_empty())
36 }
37
38 pub fn outbox(&self) -> String {
39 format!("{}/outbox", self.user_id())
40 }
41
42 pub async fn refresh(
43 auth: Auth,
44 set_token: WriteSignal<Option<String>>,
45 set_userid: WriteSignal<Option<String>>,
46 ) -> bool {
47 if let Some(tok) = auth.token.get_untracked() {
48 match crate::Http::request::<>(
49 Method::PATCH,
50 &format!("{URL_BASE}/auth"),
51 Some(&serde_json::json!({"token": tok})),
52 auth,
53 )
54 .await
55 {
56 Err(e) => tracing::error!("could not refresh token: {e}"),
57 Ok(res) => match res.error_for_status() {
58 Err(e) => tracing::error!("server rejected refresh: {e}"),
59 Ok(doc) => match doc.json::<AuthResponse>().await {
60 Err(e) => tracing::error!("failed parsing auth response: {e}"),
61 Ok(auth) => {
62 set_token.set(Some(auth.token));
63 set_userid.set(Some(auth.user));
64 return true;
65 },
66 }
67 }
68 }
69 }
70 false
71 }
72}