1
+ use crate :: email:: EmailMessage ;
1
2
use crate :: models:: ApiToken ;
2
3
use crate :: schema:: api_tokens;
3
4
use crate :: views:: EncodableApiTokenWithToken ;
@@ -20,6 +21,7 @@ use diesel::sql_types::Timestamptz;
20
21
use diesel_async:: RunQueryDsl ;
21
22
use http:: StatusCode ;
22
23
use http:: request:: Parts ;
24
+ use minijinja:: context;
23
25
use secrecy:: ExposeSecret ;
24
26
25
27
#[ derive( Deserialize ) ]
@@ -171,17 +173,12 @@ pub async fn create_api_token(
171
173
. build ( ) ;
172
174
173
175
if let Some ( recipient) = recipient {
174
- let email = NewTokenEmail {
175
- token_name : & new. api_token . name ,
176
- user_name : & user. gh_login ,
177
- domain : & app. emails . domain ,
178
- } ;
179
-
180
176
// At this point the token has been created so failing to send the
181
177
// email should not cause an error response to be returned to the
182
178
// caller.
183
- let email_ret = app. emails . send ( & recipient, email) . await ;
184
- if let Err ( e) = email_ret {
179
+ if let Err ( e) =
180
+ send_creation_email ( & app. emails , & recipient, & new. api_token . name , & user. gh_login ) . await
181
+ {
185
182
error ! ( "Failed to send token creation email: {e}" )
186
183
}
187
184
}
@@ -286,28 +283,17 @@ pub async fn revoke_current_api_token(app: AppState, req: Parts) -> AppResult<Re
286
283
Ok ( StatusCode :: NO_CONTENT . into_response ( ) )
287
284
}
288
285
289
- struct NewTokenEmail < ' a > {
290
- token_name : & ' a str ,
291
- user_name : & ' a str ,
292
- domain : & ' a str ,
293
- }
294
-
295
- impl crate :: email:: Email for NewTokenEmail < ' _ > {
296
- fn subject ( & self ) -> String {
297
- format ! ( "crates.io: New API token \" {}\" created" , self . token_name)
298
- }
299
-
300
- fn body ( & self ) -> String {
301
- format ! (
302
- "\
303
- Hello {user_name}!
304
-
305
- A new API token with the name \" {token_name}\" was recently added to your {domain} account.
306
-
307
- If this wasn't you, you should revoke the token immediately: https://{domain}/settings/tokens" ,
308
- token_name = self . token_name,
309
- user_name = self . user_name,
310
- domain = self . domain,
311
- )
312
- }
286
+ async fn send_creation_email (
287
+ emails : & crate :: Emails ,
288
+ recipient : & str ,
289
+ token_name : & str ,
290
+ user_name : & str ,
291
+ ) -> anyhow:: Result < ( ) > {
292
+ let context = context ! {
293
+ token_name,
294
+ user_name,
295
+ domain => emails. domain,
296
+ } ;
297
+ let email = EmailMessage :: from_template ( "new_token" , context) ?;
298
+ Ok ( emails. send ( recipient, email) . await ?)
313
299
}
0 commit comments