Skip to content
Clone
f0a1552
56 lines 2.2 KB Rust
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>) -> 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;" {
"Enter the following code to continue. It expires in "
(minutes)
" minutes."
}
div class="code" { (code) }
@if let Some(url) = link {
p style="margin:24px 0 0;" {
a href=(url) class="btn" { "Verify email" }
}
p class="muted" style="margin:16px 0 0;" {
"If the button doesn't work, copy this link into your browser:"
}
p style="word-break:break-all;font-size:13px;color:#2563eb;margin:4px 0 0;" { (url) }
}
p class="muted" style="margin:16px 0 0;" {
"If you didn't request this, you can safely ignore this email."
}
};
mail_shell(purpose, body)
}
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);
mail_verify_code(code, minutes, purpose, link.as_deref())
}
fn build_link(vars: &serde_json::Value) -> Option<String> {
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))
}