mas_handlers/views/
app.rs1use axum::{
8 extract::{Query, State},
9 response::{Html, IntoResponse},
10};
11use mas_axum_utils::{FancyError, cookies::CookieJar};
12use mas_router::{PostAuthAction, UrlBuilder};
13use mas_storage::{BoxClock, BoxRepository, BoxRng};
14use mas_templates::{AppContext, TemplateContext, Templates};
15use serde::Deserialize;
16
17use crate::{
18 BoundActivityTracker, PreferredLanguage,
19 session::{SessionOrFallback, load_session_or_fallback},
20};
21
22#[derive(Deserialize)]
23pub struct Params {
24 #[serde(default, flatten)]
25 action: Option<mas_router::AccountAction>,
26}
27
28#[tracing::instrument(name = "handlers.views.app.get", skip_all, err)]
29pub async fn get(
30 PreferredLanguage(locale): PreferredLanguage,
31 State(templates): State<Templates>,
32 activity_tracker: BoundActivityTracker,
33 State(url_builder): State<UrlBuilder>,
34 Query(Params { action }): Query<Params>,
35 mut repo: BoxRepository,
36 clock: BoxClock,
37 mut rng: BoxRng,
38 cookie_jar: CookieJar,
39) -> Result<impl IntoResponse, FancyError> {
40 let (cookie_jar, maybe_session) = match load_session_or_fallback(
41 cookie_jar, &clock, &mut rng, &templates, &locale, &mut repo,
42 )
43 .await?
44 {
45 SessionOrFallback::MaybeSession {
46 cookie_jar,
47 maybe_session,
48 ..
49 } => (cookie_jar, maybe_session),
50 SessionOrFallback::Fallback { response } => return Ok(response),
51 };
52
53 let Some(session) = maybe_session else {
55 return Ok((
56 cookie_jar,
57 url_builder.redirect(&mas_router::Login::and_then(
58 PostAuthAction::manage_account(action),
59 )),
60 )
61 .into_response());
62 };
63
64 activity_tracker
65 .record_browser_session(&clock, &session)
66 .await;
67
68 let ctx = AppContext::from_url_builder(&url_builder).with_language(locale);
69 let content = templates.render_app(&ctx)?;
70
71 Ok((cookie_jar, Html(content)).into_response())
72}
73
74#[tracing::instrument(name = "handlers.views.app.get_anonymous", skip_all, err)]
78pub async fn get_anonymous(
79 PreferredLanguage(locale): PreferredLanguage,
80 State(templates): State<Templates>,
81 State(url_builder): State<UrlBuilder>,
82) -> Result<impl IntoResponse, FancyError> {
83 let ctx = AppContext::from_url_builder(&url_builder).with_language(locale);
84 let content = templates.render_app(&ctx)?;
85
86 Ok(Html(content).into_response())
87}