Skip to main content

upub_web/
auth.rs

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		// TODO maybe cache this?? how often do i need it?
22		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}