use i18n::{UiLocale, catalog}; use maud::Markup; use maud::html; use super::{append_query, mail_shell, url_join}; pub fn mail_verify_code( code: &str, minutes: u64, purpose: &str, link: Option<&str>, locale: UiLocale, ) -> Markup { let body = html! { h1 style="font-size:24px;font-weight:700;margin:0 0 8px;" { (purpose) } p style="color:#374151;margin:0 0 8px;" { (catalog::verify_body(locale, minutes)) } div class="code" { (code) } @if let Some(url) = link { p style="margin:24px 0 0;" { a href=(url) class="btn" { (catalog::verify_verify_button(locale)) } } p class="muted" style="margin:16px 0 0;" { (catalog::link_fallback(locale)) } p style="word-break:break-all;font-size:13px;color:#2563eb;margin:4px 0 0;" { (url) } } p class="muted" style="margin:16px 0 0;" { (catalog::ignore_if_unrequested(locale)) } }; mail_shell(purpose, body, locale) } pub fn render(vars: &serde_json::Value) -> Markup { let code = vars.get("code").and_then(|v| v.as_str()).unwrap_or(""); let minutes = vars.get("minutes").and_then(|v| v.as_u64()).unwrap_or(0); let purpose = vars .get("purpose") .and_then(|v| v.as_str()) .unwrap_or("Verification"); let link = build_link(vars); // Templates registered through `render_and_send` receive the already // localized `purpose`; the locale only drives the surrounding chrome. let locale = vars .get("locale") .and_then(|v| v.as_str()) .and_then(UiLocale::parse) .unwrap_or(UiLocale::En); mail_verify_code(code, minutes, purpose, link.as_deref(), locale) } fn build_link(vars: &serde_json::Value) -> Option { let base_url = vars.get("base_url").and_then(|v| v.as_str())?; let email = vars.get("email").and_then(|v| v.as_str())?; let temp_id = vars.get("temp_id").and_then(|v| v.as_str())?; let code = vars.get("code").and_then(|v| v.as_str()).unwrap_or(""); let mut query = vec![("email", email), ("temp_id", temp_id), ("code", code)]; // Optional slug (signup / password_reset / ...); the human-readable // `purpose` var is a heading and must not leak into the URL. let purpose_slug; if let Some(slug) = vars.get("purpose_slug").and_then(|v| v.as_str()) { purpose_slug = slug; query.push(("purpose", purpose_slug)); } Some(append_query( &url_join(base_url, "/auth/verify-email"), &query, )) }