|
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