1use headless_lms_models::{
2 email_templates::{EmailTemplateNew, EmailTemplateType, insert_email_template},
3 user_passwords::insert_password_reset_token,
4};
5use serde_json::json;
6use sqlx::{Pool, Postgres};
7use uuid::Uuid;
8
9use super::seed_users::SeedUsersResult;
10
11pub async fn seed_generic_emails(
12 db_pool: Pool<Postgres>,
13 seed_users_result: SeedUsersResult,
14) -> anyhow::Result<()> {
15 info!("inserting password reset emails");
16
17 let mut conn = db_pool.acquire().await?;
18
19 let english_subject = Some("Reset password request");
20 let english_body = json!([
21 {
22 "type": "core/paragraph",
23 "isValid": true,
24 "clientId": "95acea49-1c92-4d54-9854-707e1bfee010",
25 "attributes": {
26 "content": "Hello, it seems you requested a password reset.",
27 "drop_cap": false
28 },
29 "innerBlocks": []
30 },
31 {
32 "type": "core/paragraph",
33 "isValid": true,
34 "clientId": "ceac591d-b291-40b2-8da7-6f437a6a8fce",
35 "attributes": {
36 "content": "You can reset your password here: {{RESET_LINK}}",
37 "drop_cap": false
38 },
39 "innerBlocks": []
40 },
41 {
42 "type": "core/paragraph",
43 "isValid": true,
44 "clientId": "6a4165a1-38e1-4a17-b364-5f265afc7d23",
45 "attributes": {
46 "content": "If you did not request a password reset, please ignore this message.",
47 "drop_cap": false
48 },
49 "innerBlocks": []
50 }
51 ]);
52
53 let english_template = EmailTemplateNew {
54 template_type: EmailTemplateType::ResetPasswordEmail,
55 language: Some("en".to_string()),
56 content: Some(english_body),
57 subject: english_subject.map(|s| s.to_string()),
58 };
59
60 insert_email_template(&mut conn, None, english_template, english_subject).await?;
61
62 let finnish_subject = Some("Salasanan palautuspyyntö");
63 let finnish_body = json!([
64 {
65 "type": "core/paragraph",
66 "isValid": true,
67 "clientId": "a9de49ff-919f-44b4-a085-9210ce0da94b",
68 "attributes": {
69 "content": "Hei, olet pyytänyt salasanan palautusta.",
70 "drop_cap": false
71 },
72 "innerBlocks": []
73 },
74 {
75 "type": "core/paragraph",
76 "isValid": true,
77 "clientId": "c145bae4-9ff5-4194-8913-50f8900c20c8",
78 "attributes": {
79 "content": "Voit palauttaa salasanasi tästä: {{RESET_LINK}}",
80 "drop_cap": false
81 },
82 "innerBlocks": []
83 },
84 {
85 "type": "core/paragraph",
86 "isValid": true,
87 "clientId": "ebd0d430-0ae3-4b85-9e8e-96481660ded4",
88 "attributes": {
89 "content": "Jos et pyytänyt salasanan palautusta, voit jättää tämän viestin huomiotta.",
90 "drop_cap": false
91 },
92 "innerBlocks": []
93 }
94 ]);
95
96 let finnish_template = EmailTemplateNew {
97 template_type: EmailTemplateType::ResetPasswordEmail,
98 language: Some("fi".to_string()),
99 content: Some(finnish_body),
100 subject: finnish_subject.map(|s| s.to_string()),
101 };
102
103 insert_email_template(&mut conn, None, finnish_template, finnish_subject).await?;
104
105 info!("inserting password reset token for user");
106 let SeedUsersResult { sign_up_user, .. } = seed_users_result;
107 insert_password_reset_token(
108 &mut conn,
109 sign_up_user,
110 Uuid::parse_str("5a831370-6b7e-4ece-b962-6bc31c28fe53")?,
111 )
112 .await?;
113
114 info!("inserting delete account email");
115
116 let delete_subject = Some("Account deletion code");
117 let delete_body = json!([
118 {
119 "type": "core/paragraph",
120 "isValid": true,
121 "clientId": "11111111-1111-1111-1111-111111111111",
122 "attributes": {
123 "content": "Hello, it seems you requested a code for deleting your account",
124 "drop_cap": false
125 },
126 "innerBlocks": []
127 },
128 {
129 "type": "core/paragraph",
130 "isValid": true,
131 "clientId": "22222222-2222-2222-2222-222222222222",
132 "attributes": {
133 "content": "Use this verification code to delete your account: {{CODE}}",
134 "drop_cap": false
135 },
136 "innerBlocks": []
137 },
138 {
139 "type": "core/paragraph",
140 "isValid": true,
141 "clientId": "33333333-3333-3333-3333-333333333333",
142 "attributes": {
143 "content": "If you did not request a code, please ignore this message.",
144 "drop_cap": false
145 },
146 "innerBlocks": []
147 }
148 ]);
149
150 let delete_template = EmailTemplateNew {
151 template_type: EmailTemplateType::DeleteUserEmail,
152 language: Some("en".to_string()),
153 content: Some(delete_body),
154 subject: delete_subject.map(|s| s.to_string()),
155 };
156
157 insert_email_template(&mut conn, None, delete_template, delete_subject).await?;
158
159 info!("inserting confirm email code email");
160
161 let confirm_subject = Some("Email verification code");
162 let confirm_body = json!([
163 {
164 "type": "core/paragraph",
165 "isValid": true,
166 "clientId": "44444444-4444-4444-4444-444444444444",
167 "attributes": {
168 "content": "Hello, please use this code to verify your email address",
169 "drop_cap": false
170 },
171 "innerBlocks": []
172 },
173 {
174 "type": "core/paragraph",
175 "isValid": true,
176 "clientId": "55555555-5555-5555-5555-555555555555",
177 "attributes": {
178 "content": "Your verification code is: {{CODE}}",
179 "drop_cap": false
180 },
181 "innerBlocks": []
182 },
183 {
184 "type": "core/paragraph",
185 "isValid": true,
186 "clientId": "66666666-6666-6666-6666-666666666666",
187 "attributes": {
188 "content": "If you did not request this code, please ignore this message.",
189 "drop_cap": false
190 },
191 "innerBlocks": []
192 }
193 ]);
194
195 let confirm_template = EmailTemplateNew {
196 template_type: EmailTemplateType::ConfirmEmailCode,
197 language: Some("en".to_string()),
198 content: Some(confirm_body),
199 subject: confirm_subject.map(|s| s.to_string()),
200 };
201
202 insert_email_template(&mut conn, None, confirm_template, confirm_subject).await?;
203
204 seed_email_ownership_verification_templates(&mut conn).await?;
205 seed_account_linking_templates(&mut conn).await?;
206 seed_credit_registration_status_templates(&mut conn).await?;
207
208 Ok(())
209}
210
211async fn seed_account_linking_templates(conn: &mut sqlx::PgConnection) -> anyhow::Result<()> {
216 info!("inserting credit registration account linking emails");
217
218 let english_subject = Some("Link your student number to register your credits");
219 let english_body = json!([
220 {
221 "type": "core/paragraph",
222 "isValid": true,
223 "clientId": "d1000000-0000-0000-0000-000000000001",
224 "attributes": {
225 "content": "Hello {{NAME}}, we can see your enrolment on {{COURSE_NAME}}. To register your credits in Sisu, we need to link your student number to your account on courses.mooc.fi.",
226 "drop_cap": false
227 },
228 "innerBlocks": []
229 },
230 {
231 "type": "core/paragraph",
232 "isValid": true,
233 "clientId": "d1000000-0000-0000-0000-000000000002",
234 "attributes": {
235 "content": "Log in to courses.mooc.fi with the account you use for the course. Then open this confirmation link to link student number {{STUDENT_NUMBER}} to it: {{LINK}}",
236 "drop_cap": false
237 },
238 "innerBlocks": []
239 },
240 {
241 "type": "core/paragraph",
242 "isValid": true,
243 "clientId": "d1000000-0000-0000-0000-000000000003",
244 "attributes": {
245 "content": "The link works for 14 days and only once. You got this email because you are enrolled on {{COURSE_NAME}} at the University of Helsinki. If this was not you, you can ignore this email.",
246 "drop_cap": false
247 },
248 "innerBlocks": []
249 }
250 ]);
251
252 insert_email_template(
253 conn,
254 None,
255 EmailTemplateNew {
256 template_type: EmailTemplateType::CreditRegistrationAccountLinking,
257 language: Some("en".to_string()),
258 content: Some(english_body),
259 subject: english_subject.map(|s| s.to_string()),
260 },
261 english_subject,
262 )
263 .await?;
264
265 let finnish_subject = Some("Liitä opiskelijanumerosi, jotta voimme kirjata opintopisteesi");
266 let finnish_body = json!([
267 {
268 "type": "core/paragraph",
269 "isValid": true,
270 "clientId": "d2000000-0000-0000-0000-000000000001",
271 "attributes": {
272 "content": "Hei {{NAME}}, näemme ilmoittautumisesi kurssille {{COURSE_NAME}}. Jotta voimme kirjata opintopisteesi Sisuun, meidän pitää liittää opiskelijanumerosi courses.mooc.fi-tiliisi.",
273 "drop_cap": false
274 },
275 "innerBlocks": []
276 },
277 {
278 "type": "core/paragraph",
279 "isValid": true,
280 "clientId": "d2000000-0000-0000-0000-000000000002",
281 "attributes": {
282 "content": "Kirjaudu courses.mooc.fi-palveluun sillä tilillä, jolla teet kurssia. Avaa sitten tämä vahvistuslinkki, niin opiskelijanumero {{STUDENT_NUMBER}} liitetään tiliisi: {{LINK}}",
283 "drop_cap": false
284 },
285 "innerBlocks": []
286 },
287 {
288 "type": "core/paragraph",
289 "isValid": true,
290 "clientId": "d2000000-0000-0000-0000-000000000003",
291 "attributes": {
292 "content": "Linkki toimii 14 päivää ja vain kerran. Sait tämän viestin, koska olet ilmoittautunut Helsingin yliopiston kurssille {{COURSE_NAME}}. Jos et ole ilmoittautunut, voit jättää viestin huomiotta.",
293 "drop_cap": false
294 },
295 "innerBlocks": []
296 }
297 ]);
298
299 insert_email_template(
300 conn,
301 None,
302 EmailTemplateNew {
303 template_type: EmailTemplateType::CreditRegistrationAccountLinking,
304 language: Some("fi".to_string()),
305 content: Some(finnish_body),
306 subject: finnish_subject.map(|s| s.to_string()),
307 },
308 finnish_subject,
309 )
310 .await?;
311
312 Ok(())
313}
314
315async fn seed_email_ownership_verification_templates(
321 conn: &mut sqlx::PgConnection,
322) -> anyhow::Result<()> {
323 info!("inserting email address verification emails");
324
325 let english_subject = Some("Confirm your email address");
326 let english_body = json!([
327 {
328 "type": "core/paragraph",
329 "isValid": true,
330 "clientId": "77777777-7777-7777-7777-777777777777",
331 "attributes": {
332 "content": "Hello, please use this code to confirm the email address on your account.",
333 "drop_cap": false
334 },
335 "innerBlocks": []
336 },
337 {
338 "type": "core/paragraph",
339 "isValid": true,
340 "clientId": "88888888-8888-8888-8888-888888888888",
341 "attributes": {
342 "content": "Your confirmation code is: {{CODE}}",
343 "drop_cap": false
344 },
345 "innerBlocks": []
346 },
347 {
348 "type": "core/paragraph",
349 "isValid": true,
350 "clientId": "99999999-9999-9999-9999-999999999999",
351 "attributes": {
352 "content": "If you did not request this, you can ignore this message. Nothing changes until the code is entered.",
353 "drop_cap": false
354 },
355 "innerBlocks": []
356 }
357 ]);
358
359 insert_email_template(
360 conn,
361 None,
362 EmailTemplateNew {
363 template_type: EmailTemplateType::VerifyEmailAddress,
364 language: Some("en".to_string()),
365 content: Some(english_body),
366 subject: english_subject.map(|s| s.to_string()),
367 },
368 english_subject,
369 )
370 .await?;
371
372 let finnish_subject = Some("Vahvista sähköpostiosoitteesi");
373 let finnish_body = json!([
374 {
375 "type": "core/paragraph",
376 "isValid": true,
377 "clientId": "aaaaaaaa-7777-7777-7777-777777777777",
378 "attributes": {
379 "content": "Hei, vahvista tilisi sähköpostiosoite tällä koodilla.",
380 "drop_cap": false
381 },
382 "innerBlocks": []
383 },
384 {
385 "type": "core/paragraph",
386 "isValid": true,
387 "clientId": "bbbbbbbb-8888-8888-8888-888888888888",
388 "attributes": {
389 "content": "Vahvistuskoodisi on: {{CODE}}",
390 "drop_cap": false
391 },
392 "innerBlocks": []
393 },
394 {
395 "type": "core/paragraph",
396 "isValid": true,
397 "clientId": "cccccccc-9999-9999-9999-999999999999",
398 "attributes": {
399 "content": "Jos et pyytänyt tätä, voit jättää viestin huomiotta. Mikään ei muutu ennen kuin koodi syötetään.",
400 "drop_cap": false
401 },
402 "innerBlocks": []
403 }
404 ]);
405
406 insert_email_template(
407 conn,
408 None,
409 EmailTemplateNew {
410 template_type: EmailTemplateType::VerifyEmailAddress,
411 language: Some("fi".to_string()),
412 content: Some(finnish_body),
413 subject: finnish_subject.map(|s| s.to_string()),
414 },
415 finnish_subject,
416 )
417 .await?;
418
419 Ok(())
420}
421
422async fn seed_credit_registration_status_templates(
425 conn: &mut sqlx::PgConnection,
426) -> anyhow::Result<()> {
427 info!("inserting credit registration status emails");
428
429 let templates: [(EmailTemplateType, &str, &str, &[&str]); 4] = [
430 (
431 EmailTemplateType::CreditRegistrationActionNeeded,
432 "en",
433 "One more step to get your credits registered",
434 &[
435 "Hello, congratulations on completing {{COURSE_NAME}}! You have earned {{CREDITS}} credits.",
436 "To get the credits registered in Sisu, you need to be enrolled on the course. You can see how to enrol here: {{STATUS_LINK}}",
437 "After that you do not need to do anything else: we check your enrolment regularly and register your credits automatically. If you have already enrolled, you can ignore this message.",
438 "Best regards,<br>MOOC.fi",
439 ],
440 ),
441 (
442 EmailTemplateType::CreditRegistrationActionNeeded,
443 "fi",
444 "Vielä yksi vaihe opintopisteiden kirjaamiseen",
445 &[
446 "Hei, onnittelut kurssin {{COURSE_NAME}} suorittamisesta! Olet ansainnut {{CREDITS}} op.",
447 "Jotta opintopisteet voidaan kirjata Sisuun, sinun pitää olla ilmoittautunut kurssille. Näet ilmoittautumisohjeet täältä: {{STATUS_LINK}}",
448 "Sen jälkeen sinun ei tarvitse tehdä muuta: tarkistamme ilmoittautumisesi säännöllisesti ja kirjaamme opintopisteesi automaattisesti. Jos olet jo ilmoittautunut, voit jättää tämän viestin huomiotta.",
449 "Terveisin,<br>MOOC.fi",
450 ],
451 ),
452 (
453 EmailTemplateType::CreditRegistrationRegistered,
454 "en",
455 "Your credits have been registered",
456 &[
457 "Hello, your {{CREDITS}} credits for {{COURSE_NAME}} are now registered in Sisu.",
458 "You do not need to do anything else. You can see the details here: {{STATUS_LINK}}",
459 "Best regards,<br>MOOC.fi",
460 ],
461 ),
462 (
463 EmailTemplateType::CreditRegistrationRegistered,
464 "fi",
465 "Opintopisteesi on kirjattu",
466 &[
467 "Hei, kurssin {{COURSE_NAME}} opintopisteesi ({{CREDITS}} op) on nyt kirjattu Sisuun.",
468 "Sinun ei tarvitse tehdä muuta. Näet tiedot täältä: {{STATUS_LINK}}",
469 "Terveisin,<br>MOOC.fi",
470 ],
471 ),
472 ];
473
474 for (template_index, (template_type, language, subject, paragraphs)) in
475 templates.into_iter().enumerate()
476 {
477 let blocks: Vec<_> = paragraphs
478 .iter()
479 .enumerate()
480 .map(|(paragraph_index, content)| {
481 json!({
482 "type": "core/paragraph",
483 "isValid": true,
484 "clientId": format!(
485 "d{}000000-0000-0000-0000-{:012}",
486 template_index + 3,
487 paragraph_index + 1
488 ),
489 "attributes": {
490 "content": content,
491 "drop_cap": false
492 },
493 "innerBlocks": []
494 })
495 })
496 .collect();
497
498 insert_email_template(
499 conn,
500 None,
501 EmailTemplateNew {
502 template_type,
503 language: Some(language.to_string()),
504 content: Some(json!(blocks)),
505 subject: Some(subject.to_string()),
506 },
507 Some(subject),
508 )
509 .await?;
510 }
511
512 Ok(())
513}