Skip to main content

allowthem_server/
browser_templates.rs

1use std::sync::Arc;
2
3use axum::response::Html;
4use minijinja::Environment;
5
6use crate::browser_error::BrowserError;
7
8const BASE_HTML: &str = include_str!("templates/base.html");
9const LOGIN_HTML: &str = include_str!("templates/login.html");
10const REGISTER_HTML: &str = include_str!("templates/register.html");
11const SETTINGS_HTML: &str = include_str!("templates/settings.html");
12const CONSENT_HTML: &str = include_str!("templates/consent.html");
13const FORGOT_PASSWORD_HTML: &str = include_str!("templates/forgot_password.html");
14const RESET_PASSWORD_HTML: &str = include_str!("templates/reset_password.html");
15const MFA_SETUP_HTML: &str = include_str!("templates/mfa_setup.html");
16const MFA_RECOVERY_HTML: &str = include_str!("templates/mfa_recovery.html");
17const MFA_CHALLENGE_HTML: &str = include_str!("templates/mfa_challenge.html");
18
19/// Register the default browser templates into an existing environment.
20///
21/// Useful for consumers (like the standalone binary) that need to extend
22/// the default template set with additional templates of their own.
23pub fn add_default_browser_templates(env: &mut Environment<'static>) {
24    env.add_template_owned("base.html", BASE_HTML)
25        .expect("base.html");
26    env.add_template_owned("login.html", LOGIN_HTML)
27        .expect("login.html");
28    env.add_template_owned("register.html", REGISTER_HTML)
29        .expect("register.html");
30    env.add_template_owned("settings.html", SETTINGS_HTML)
31        .expect("settings.html");
32    env.add_template_owned("consent.html", CONSENT_HTML)
33        .expect("consent.html");
34    env.add_template_owned("forgot_password.html", FORGOT_PASSWORD_HTML)
35        .expect("forgot_password.html");
36    env.add_template_owned("reset_password.html", RESET_PASSWORD_HTML)
37        .expect("reset_password.html");
38    env.add_template_owned("mfa_setup.html", MFA_SETUP_HTML)
39        .expect("mfa_setup.html");
40    env.add_template_owned("mfa_recovery.html", MFA_RECOVERY_HTML)
41        .expect("mfa_recovery.html");
42    env.add_template_owned("mfa_challenge.html", MFA_CHALLENGE_HTML)
43        .expect("mfa_challenge.html");
44}
45
46pub fn build_default_browser_env() -> Arc<Environment<'static>> {
47    let mut env = Environment::new();
48    add_default_browser_templates(&mut env);
49    Arc::new(env)
50}
51
52pub fn render(
53    env: &Environment<'_>,
54    template_name: &str,
55    ctx: minijinja::value::Value,
56) -> Result<Html<String>, BrowserError> {
57    let tmpl = env.get_template(template_name)?;
58    let rendered = tmpl.render(ctx)?;
59    Ok(Html(rendered))
60}
61
62#[cfg(test)]
63mod tests {
64    use super::*;
65
66    #[test]
67    fn default_env_loads_all_browser_templates() {
68        let env = build_default_browser_env();
69        for name in [
70            "base.html",
71            "login.html",
72            "register.html",
73            "settings.html",
74            "consent.html",
75            "forgot_password.html",
76            "reset_password.html",
77            "mfa_setup.html",
78            "mfa_recovery.html",
79            "mfa_challenge.html",
80        ] {
81            assert!(
82                env.get_template(name).is_ok(),
83                "template {name} should be loadable"
84            );
85        }
86    }
87
88    #[test]
89    fn render_produces_html() {
90        let env = build_default_browser_env();
91        let result = render(
92            &env,
93            "login.html",
94            minijinja::context! {
95                csrf_token => "test",
96                is_production => false,
97            },
98        );
99        assert!(result.is_ok());
100    }
101}