Skip to main content

max / makenotwork

5.8 KB · 220 lines History Blame Raw
1 //! Authentication and account action email templates.
2
3 use crate::email::EmailClient;
4 use crate::error::Result;
5
6 impl EmailClient {
7 /// Send a password reset email
8 pub async fn send_password_reset(
9 &self,
10 to_email: &str,
11 to_name: Option<&str>,
12 reset_url: &str,
13 ) -> Result<()> {
14 let subject = "Reset your password";
15 let body = format!(
16 r"Hi{name},
17
18 You requested to reset your password. Click the link below to set a new password:
19
20 {url}
21
22 This link expires in 15 minutes. If you didn't request this, you can ignore this email.
23
24 - Makenotwork",
25 name = crate::email::greeting(to_name),
26 url = reset_url
27 );
28
29 self.transport.send_email(to_email, subject, &body).await
30 }
31
32 /// Send an email verification email
33 pub async fn send_verification(
34 &self,
35 to_email: &str,
36 to_name: Option<&str>,
37 verify_url: &str,
38 ) -> Result<()> {
39 let subject = "Verify your email";
40 let body = format!(
41 r"Hi{name},
42
43 Please verify your email address by clicking the link below:
44
45 {url}
46
47 This link expires in 24 hours.
48
49 - Makenotwork",
50 name = crate::email::greeting(to_name),
51 url = verify_url
52 );
53
54 self.transport.send_email(to_email, subject, &body).await
55 }
56
57 /// Sent when someone tries to sign up with an email that already has an
58 /// account. The signup page deliberately does not reveal that the address is
59 /// registered (enumeration defense); this email is the channel that reaches
60 /// the real owner so they can recover, since only they receive it.
61 pub async fn send_account_exists(
62 &self,
63 to_email: &str,
64 login_url: &str,
65 reset_url: &str,
66 ) -> Result<()> {
67 let subject = "You already have a Makenotwork account";
68 let body = format!(
69 r"Hi,
70
71 Someone (probably you) just tried to sign up for Makenotwork with this email
72 address, but you already have an account.
73
74 To sign in:
75
76 {login_url}
77
78 If you've forgotten your password, you can reset it here:
79
80 {reset_url}
81
82 If this wasn't you, nothing was created or changed and you can safely ignore
83 this email.
84
85 - Makenotwork",
86 );
87
88 self.transport.send_email(to_email, subject, &body).await
89 }
90
91 /// Send an account lockout notification
92 pub async fn send_lockout_notification(
93 &self,
94 to_email: &str,
95 to_name: Option<&str>,
96 login_link_url: Option<&str>,
97 ) -> Result<()> {
98 let subject = "Security alert: Account locked";
99 let body = format!(
100 r"Hi{name},
101
102 Your account has been temporarily locked due to multiple failed login attempts.
103
104 {login_link}
105
106 If this wasn't you, please contact support immediately.
107
108 - Makenotwork",
109 name = crate::email::greeting(to_name),
110 login_link = login_link_url.map_or_else(
111 || "Your account will unlock automatically in 15 minutes.".to_string(),
112 |url| format!(
113 "Use this link to log in securely:\n\n{url}\n\nThis link expires in 15 minutes."
114 )
115 )
116 );
117
118 self.transport.send_email(to_email, subject, &body).await
119 }
120
121 /// Send a one-time login link
122 pub async fn send_login_link(
123 &self,
124 to_email: &str,
125 to_name: Option<&str>,
126 login_url: &str,
127 ) -> Result<()> {
128 let subject = "Your login link";
129 let body = format!(
130 r"Hi{name},
131
132 Click the link below to log in to your account:
133
134 {url}
135
136 This link expires in 15 minutes and can only be used once.
137
138 If you didn't request this, you can ignore this email.
139
140 - Makenotwork",
141 name = crate::email::greeting(to_name),
142 url = login_url
143 );
144
145 self.transport.send_email(to_email, subject, &body).await
146 }
147
148 /// Send account deletion confirmation email
149 pub async fn send_deletion_confirmation(
150 &self,
151 to_email: &str,
152 to_name: Option<&str>,
153 delete_url: &str,
154 ) -> Result<()> {
155 let subject = "Confirm account deletion";
156 let body = format!(
157 r"Hi{name},
158
159 You requested to delete your Makenotwork account.
160
161 IMPORTANT: This action is permanent and cannot be undone.
162
163 Clicking the link below will immediately and permanently delete:
164 - All your projects and items
165 - All uploaded content (audio, images)
166 - Your profile and account settings
167 - Your custom links
168
169 Purchases made by your fans will remain accessible to them.
170
171 To confirm deletion, click this link:
172
173 {url}
174
175 This link expires in 1 hour.
176
177 If you did not request this, do NOT click the link. Your account is safe.
178
179 - Makenotwork",
180 name = crate::email::greeting(to_name),
181 url = delete_url
182 );
183
184 self.transport.send_email(to_email, subject, &body).await
185 }
186
187 /// Send a new-device login notification
188 pub async fn send_new_login_notification(
189 &self,
190 to_email: &str,
191 to_name: Option<&str>,
192 device: Option<&str>,
193 ip: Option<&str>,
194 unsub_url: Option<&str>,
195 ) -> Result<()> {
196 let subject = "New sign-in to your account";
197 let device_line = device.unwrap_or("Unknown device");
198 let ip_line = ip.unwrap_or("Unknown");
199 let body = format!(
200 r"Hi{name},
201
202 Your account was just signed in to from a new device.
203
204 Device: {device}
205 IP address: {ip}
206
207 If this was you, no action is needed. If you don't recognize this sign-in, go to your dashboard and revoke the session under Settings > Sessions.
208
209 - Makenotwork",
210 name = crate::email::greeting(to_name),
211 device = device_line,
212 ip = ip_line,
213 );
214
215 self.transport
216 .send_email_with_unsub(to_email, subject, &body, unsub_url)
217 .await
218 }
219 }
220