mas_handlers/views/register/
mod.rs1use axum::{
7 extract::State,
8 response::{Html, IntoResponse, Response},
9};
10use axum_extra::extract::Query;
11use mas_axum_utils::{InternalError, SessionInfoExt, cookies::CookieJar, csrf::CsrfExt as _};
12use mas_data_model::{BoxClock, BoxRng, SiteConfig};
13use mas_router::{PasswordRegister, UpstreamOAuth2Authorize, UrlBuilder};
14use mas_storage::BoxRepository;
15use mas_templates::{RegisterContext, TemplateContext, Templates};
16
17use super::shared::OptionalPostAuthAction;
18use crate::{BoundActivityTracker, PreferredLanguage};
19
20mod cookie;
21pub(crate) mod password;
22pub(crate) mod steps;
23
24pub use self::cookie::UserRegistrationSessions as UserRegistrationSessionsCookie;
25
26#[tracing::instrument(name = "handlers.views.register.get", skip_all)]
27pub(crate) async fn get(
28 mut rng: BoxRng,
29 clock: BoxClock,
30 PreferredLanguage(locale): PreferredLanguage,
31 State(templates): State<Templates>,
32 State(url_builder): State<UrlBuilder>,
33 State(site_config): State<SiteConfig>,
34 mut repo: BoxRepository,
35 activity_tracker: BoundActivityTracker,
36 Query(query): Query<OptionalPostAuthAction>,
37 cookie_jar: CookieJar,
38) -> Result<Response, InternalError> {
39 let (csrf_token, cookie_jar) = cookie_jar.csrf_token(&clock, &mut rng);
40 let (session_info, cookie_jar) = cookie_jar.session_info();
41
42 let maybe_session = session_info.load_active_session(&mut repo).await?;
43
44 if let Some(session) = maybe_session {
45 activity_tracker
46 .record_browser_session(&clock, &session)
47 .await;
48
49 let reply = query.go_next(&url_builder);
50 return Ok((cookie_jar, reply).into_response());
51 }
52
53 let providers = repo.upstream_oauth_provider().all_enabled().await?;
54
55 if !site_config.password_registration_enabled && providers.len() == 1 {
58 let provider = providers.into_iter().next().unwrap();
59
60 let mut destination = UpstreamOAuth2Authorize::new(provider.id);
61
62 if let Some(action) = query.post_auth_action {
63 destination = destination.and_then(action);
64 }
65
66 return Ok((cookie_jar, url_builder.redirect(&destination)).into_response());
67 }
68
69 if site_config.password_registration_enabled && providers.is_empty() {
72 let mut destination = PasswordRegister::default();
73
74 if let Some(action) = query.post_auth_action {
75 destination = destination.and_then(action);
76 }
77
78 return Ok((cookie_jar, url_builder.redirect(&destination)).into_response());
79 }
80
81 let mut ctx = RegisterContext::new(providers);
82 let post_action = query
83 .load_context(&mut repo)
84 .await
85 .map_err(InternalError::from_anyhow)?;
86 if let Some(action) = post_action {
87 ctx = ctx.with_post_action(action);
88 }
89
90 let ctx = ctx.with_csrf(csrf_token.form_value()).with_language(locale);
91
92 let content = templates.render_register(&ctx)?;
93
94 Ok((cookie_jar, Html(content)).into_response())
95}