|
1 | 1 | use crate::models::ApiToken; |
2 | 2 | use crate::schema::api_tokens; |
3 | | -use crate::{Emails, email::Email, models::User, worker::Environment}; |
| 3 | +use crate::{Emails, email::EmailMessage, models::User, worker::Environment}; |
4 | 4 | use chrono::SecondsFormat; |
5 | 5 | use crates_io_worker::BackgroundJob; |
6 | 6 | use diesel::dsl::now; |
7 | 7 | use diesel::prelude::*; |
8 | 8 | use diesel::sql_types::Timestamptz; |
9 | 9 | use diesel_async::{AsyncPgConnection, RunQueryDsl}; |
| 10 | +use minijinja::context; |
10 | 11 | use std::sync::Arc; |
11 | 12 |
|
12 | 13 | /// The threshold for the expiry notification. |
@@ -83,12 +84,15 @@ async fn handle_expiring_token( |
83 | 84 | let recipient = user.email(conn).await?; |
84 | 85 | if let Some(recipient) = recipient { |
85 | 86 | debug!("Sending expiry notification to {}…", recipient); |
86 | | - let email = ExpiryNotificationEmail { |
87 | | - name: &user.gh_login, |
88 | | - token_id: token.id, |
89 | | - token_name: &token.name, |
90 | | - expiry_date: token.expired_at.unwrap(), |
91 | | - }; |
| 87 | + let email = EmailMessage::from_template( |
| 88 | + "expiry_notification", |
| 89 | + context! { |
| 90 | + name => user.gh_login, |
| 91 | + token_id => token.id, |
| 92 | + token_name => token.name, |
| 93 | + expiry_date => token.expired_at.unwrap().to_rfc3339_opts(SecondsFormat::Secs, true) |
| 94 | + }, |
| 95 | + )?; |
92 | 96 | emails.send(&recipient, email).await?; |
93 | 97 | } else { |
94 | 98 | info!( |
@@ -134,40 +138,6 @@ pub async fn find_expiring_tokens( |
134 | 138 | .await |
135 | 139 | } |
136 | 140 |
|
137 | | -#[derive(Debug, Clone)] |
138 | | -struct ExpiryNotificationEmail<'a> { |
139 | | - name: &'a str, |
140 | | - token_id: i32, |
141 | | - token_name: &'a str, |
142 | | - expiry_date: chrono::DateTime<chrono::Utc>, |
143 | | -} |
144 | | - |
145 | | -impl Email for ExpiryNotificationEmail<'_> { |
146 | | - fn subject(&self) -> String { |
147 | | - format!( |
148 | | - "crates.io: Your API token \"{}\" is about to expire", |
149 | | - self.token_name |
150 | | - ) |
151 | | - } |
152 | | - |
153 | | - fn body(&self) -> String { |
154 | | - format!( |
155 | | - r#"Hi {}, |
156 | | -
|
157 | | -We noticed your token "{}" will expire on {}. |
158 | | -
|
159 | | -If this token is still needed, visit https://crates.io/settings/tokens/new?from={} to generate a new one. |
160 | | -
|
161 | | -Thanks, |
162 | | -The crates.io team"#, |
163 | | - self.name, |
164 | | - self.token_name, |
165 | | - self.expiry_date.to_rfc3339_opts(SecondsFormat::Secs, true), |
166 | | - self.token_id |
167 | | - ) |
168 | | - } |
169 | | -} |
170 | | - |
171 | 141 | #[cfg(test)] |
172 | 142 | mod tests { |
173 | 143 | use super::*; |
|
0 commit comments