Skip to content

Commit 4c0ef2b

Browse files
authored
Merge pull request #11482 from Turbo87/emails
emails: Standardize branding with template inheritance and polish content
2 parents deb8dc5 + 2f8600a commit 4c0ef2b

File tree

40 files changed

+346
-57
lines changed

40 files changed

+346
-57
lines changed

src/controllers/krate/snapshots/crates_io__controllers__krate__delete__tests__happy_path_new_crate-3.snap

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,15 @@ Subject: crates.io: Successfully published foo@1.0.0
88
Content-Type: text/plain; charset=utf-8
99
Content-Transfer-Encoding: quoted-printable
1010

11+
1112
Hello foo!
1213

1314
A new version of the package foo (1.0.0) was published by your account (https://crates.io/users/foo) at [0000-00-00T00:00:00Z].
1415

1516
If you have questions or security concerns, you can contact us at help@crates.io. If you would like to stop receiving these security notifications, you can disable them in your account settings.
17+
18+
--
19+
The crates.io Team
1620
----------------------------------------
1721

1822
To: foo@example.com
@@ -21,8 +25,12 @@ Subject: crates.io: Deleted "foo" crate
2125
Content-Type: text/plain; charset=utf-8
2226
Content-Transfer-Encoding: quoted-printable
2327

28+
2429
Hi foo,
2530

2631
Your "foo" crate has been deleted, per your request.
2732

2833
If you did not initiate this deletion, your account may have been compromised. Please contact us at help@crates.io.
34+
35+
--
36+
The crates.io Team

src/controllers/krate/snapshots/crates_io__controllers__krate__delete__tests__happy_path_old_crate-3.snap

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,15 @@ Subject: crates.io: Successfully published foo@1.0.0
88
Content-Type: text/plain; charset=utf-8
99
Content-Transfer-Encoding: quoted-printable
1010

11+
1112
Hello foo!
1213

1314
A new version of the package foo (1.0.0) was published by your account (https://crates.io/users/foo) at [0000-00-00T00:00:00Z].
1415

1516
If you have questions or security concerns, you can contact us at help@crates.io. If you would like to stop receiving these security notifications, you can disable them in your account settings.
17+
18+
--
19+
The crates.io Team
1620
----------------------------------------
1721

1822
To: foo@example.com
@@ -21,8 +25,12 @@ Subject: crates.io: Deleted "foo" crate
2125
Content-Type: text/plain; charset=utf-8
2226
Content-Transfer-Encoding: quoted-printable
2327

28+
2429
Hi foo,
2530

2631
Your "foo" crate has been deleted, per your request.
2732

2833
If you did not initiate this deletion, your account may have been compromised. Please contact us at help@crates.io.
34+
35+
--
36+
The crates.io Team

src/controllers/krate/snapshots/crates_io__controllers__krate__delete__tests__happy_path_really_old_crate-3.snap

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,15 @@ Subject: crates.io: Successfully published foo@1.0.0
88
Content-Type: text/plain; charset=utf-8
99
Content-Transfer-Encoding: quoted-printable
1010

11+
1112
Hello foo!
1213

1314
A new version of the package foo (1.0.0) was published by your account (https://crates.io/users/foo) at [0000-00-00T00:00:00Z].
1415

1516
If you have questions or security concerns, you can contact us at help@crates.io. If you would like to stop receiving these security notifications, you can disable them in your account settings.
17+
18+
--
19+
The crates.io Team
1620
----------------------------------------
1721

1822
To: foo@example.com
@@ -21,8 +25,12 @@ Subject: crates.io: Deleted "foo" crate
2125
Content-Type: text/plain; charset=utf-8
2226
Content-Transfer-Encoding: quoted-printable
2327

28+
2429
Hi foo,
2530

2631
Your "foo" crate has been deleted, per your request.
2732

2833
If you did not initiate this deletion, your account may have been compromised. Please contact us at help@crates.io.
34+
35+
--
36+
The crates.io Team

src/controllers/trustpub/github_configs/create/snapshots/crates_io__controllers__trustpub__github_configs__create__tests__happy_path-3.snap

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,10 @@ Subject: crates.io: Trusted Publishing configuration added to foo
88
Content-Type: text/plain; charset=utf-8
99
Content-Transfer-Encoding: quoted-printable
1010

11+
1112
Hello foo!
1213

13-
crates.io user foo added a new "Trusted Publishing" configuration for GitHub Actions to a crate that you manage (foo). Trusted publishers act as trusted users and can publish new versions of the crate automatically.
14+
crates.io user foo added a new "Trusted Publishing" configuration for GitHub Actions to a crate that you manage ("foo"). Trusted publishers act as trusted users and can publish new versions of the crate automatically.
1415

1516
Trusted Publishing configuration:
1617

@@ -21,4 +22,7 @@ Trusted Publishing configuration:
2122

2223
If you did not make this change and you think it was made maliciously, you can remove the configuration from the crate via the "Settings" tab on the crate's page.
2324

24-
If you are unable to revert the change and need to do so, you can email help@crates.io to communicate with the crates.io support team.
25+
If you are unable to revert the change and need to do so, you can email help@crates.io for assistance.
26+
27+
--
28+
The crates.io Team

src/controllers/trustpub/github_configs/delete/snapshots/crates_io__controllers__trustpub__github_configs__delete__tests__happy_path-2.snap

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,10 @@ Subject: crates.io: Trusted Publishing configuration removed from foo
88
Content-Type: text/plain; charset=utf-8
99
Content-Transfer-Encoding: quoted-printable
1010

11+
1112
Hello foo!
1213

13-
crates.io user foo removed a "Trusted Publishing" configuration for GitHub Actions from a crate that you manage (foo).
14+
crates.io user foo removed a "Trusted Publishing" configuration for GitHub Actions from a crate that you manage ("foo").
1415

1516
Trusted Publishing configuration:
1617

@@ -19,4 +20,7 @@ Trusted Publishing configuration:
1920
- Workflow filename: publish.yml
2021
- Environment: (not set)
2122

22-
If you did not make this change and you think it was made maliciously, you can email help@crates.io to communicate with the crates.io support team.
23+
If you did not make this change and you think it was made maliciously, you can email help@crates.io for assistance.
24+
25+
--
26+
The crates.io Team

src/controllers/user/snapshots/crates_io__controllers__user__email_verification__tests__happy_path-3.snap

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,16 @@ To: foo@example.com
66
From: crates.io <noreply@crates.io>
77
Subject: crates.io: Please confirm your email address
88
Content-Type: text/plain; charset=utf-8
9-
Content-Transfer-Encoding: 7bit
9+
Content-Transfer-Encoding: quoted-printable
1010

11-
Hello foo! Welcome to crates.io. Please click the
12-
link below to verify your email address. Thank you!
11+
12+
Hello foo!
13+
14+
Welcome to crates.io. Please click the link below to verify your email address:
1315

1416
https://crates.io/confirm/[confirm-token]
17+
18+
Thank you!
19+
20+
--
21+
The crates.io Team

src/email.rs

Lines changed: 48 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,24 +16,40 @@ use std::sync::LazyLock;
1616
static EMAIL_ENV: LazyLock<Environment<'static>> = LazyLock::new(|| {
1717
let mut env = Environment::new();
1818

19-
// Load templates from each email directory
19+
// Load templates from the templates directory
2020
let entries = std::fs::read_dir("src/email/templates");
2121
let entries = entries.expect("Failed to read email templates directory");
2222

2323
for entry in entries {
2424
let entry = entry.expect("Failed to read directory entry");
2525

26+
let path = entry.path();
2627
let file_type = entry.file_type().expect("Failed to get file type");
28+
29+
// Handle base template files
30+
if file_type.is_file() && path.extension().and_then(|s| s.to_str()) == Some("j2") {
31+
let template_name = entry.file_name();
32+
let template_name = template_name.to_str();
33+
let template_name = template_name.expect("Invalid UTF-8 in template filename");
34+
35+
let template_contents = std::fs::read_to_string(&path)
36+
.unwrap_or_else(|error| panic!("Failed to read template {template_name}: {error}"));
37+
38+
env.add_template_owned(template_name.to_string(), template_contents)
39+
.expect("Failed to add template");
40+
}
41+
2742
if !file_type.is_dir() {
2843
continue;
2944
}
3045

46+
// Handle email template directories
3147
let dir_name = entry.file_name();
3248
let email_name = dir_name.to_str();
3349
let email_name = email_name.expect("Invalid UTF-8 in email template directory name");
3450

3551
// Load subject.txt.j2 file
36-
let subject_path = entry.path().join("subject.txt.j2");
52+
let subject_path = path.join("subject.txt.j2");
3753
let subject_contents = std::fs::read_to_string(&subject_path).unwrap_or_else(|error| {
3854
panic!("Failed to read subject template for {email_name}: {error}")
3955
});
@@ -42,7 +58,7 @@ static EMAIL_ENV: LazyLock<Environment<'static>> = LazyLock::new(|| {
4258
.expect("Failed to add subject template");
4359

4460
// Load body.txt.j2 file
45-
let body_path = entry.path().join("body.txt.j2");
61+
let body_path = path.join("body.txt.j2");
4662
let body_contents = std::fs::read_to_string(&body_path).unwrap_or_else(|error| {
4763
panic!("Failed to read body template for {email_name}: {error}")
4864
});
@@ -234,6 +250,35 @@ pub struct StoredEmail {
234250
mod tests {
235251
use super::*;
236252
use claims::{assert_err, assert_ok};
253+
use minijinja::context;
254+
255+
#[test]
256+
fn test_user_confirm_template_inheritance() {
257+
// Test that the `user_confirm` template inherits properly from the base template
258+
let result = render_template(
259+
"user_confirm/body.txt.j2",
260+
context! {
261+
domain => "crates.io",
262+
user_name => "testuser",
263+
token => "abc123"
264+
},
265+
);
266+
assert_ok!(&result);
267+
268+
let content = result.unwrap();
269+
insta::assert_snapshot!(content, @r"
270+
Hello testuser!
271+
272+
Welcome to crates.io. Please click the link below to verify your email address:
273+
274+
https://crates.io/confirm/abc123
275+
276+
Thank you!
277+
278+
--
279+
The crates.io Team
280+
");
281+
}
237282

238283
#[tokio::test]
239284
async fn sending_to_invalid_email_fails() {

src/email/templates/admin_account/body.txt.j2

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
{% extends "base.txt.j2" %}
2+
3+
{% block content %}
14
{% if added_admins -%}
25
Granted admin access:
36

@@ -10,4 +13,5 @@ Revoked admin access:
1013
{% for admin in removed_admins -%}
1114
- {{ admin }}
1215
{% endfor -%}
13-
{% endif %}
16+
{% endif %}
17+
{% endblock %}

src/email/templates/base.txt.j2

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{% block content %}{% endblock %}
2+
--
3+
The crates.io Team

src/email/templates/config_created/body.txt.j2

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1+
{% extends "base.txt.j2" %}
2+
3+
{% block content %}
14
Hello {{ recipient }}!
25

3-
crates.io user {{ user }} added a new "Trusted Publishing" configuration for GitHub Actions to a crate that you manage ({{ krate }}). Trusted publishers act as trusted users and can publish new versions of the crate automatically.
6+
crates.io user {{ user }} added a new "Trusted Publishing" configuration for GitHub Actions to a crate that you manage ("{{ krate }}"). Trusted publishers act as trusted users and can publish new versions of the crate automatically.
47

58
Trusted Publishing configuration:
69

@@ -11,4 +14,5 @@ Trusted Publishing configuration:
1114

1215
If you did not make this change and you think it was made maliciously, you can remove the configuration from the crate via the "Settings" tab on the crate's page.
1316

14-
If you are unable to revert the change and need to do so, you can email help@crates.io to communicate with the crates.io support team.
17+
If you are unable to revert the change and need to do so, you can email help@crates.io for assistance.
18+
{% endblock %}

0 commit comments

Comments
 (0)