feat(backend): improve e-mail deliverability with sender name (#8888)

* Avoid early html encoding for the remaining '='

* Make 'EMAIL_DEFAULT_SENDER' required env

* Implement sender and recipient name on send e-mails nodemailer conform

* Fix e-mail snapshots
This commit is contained in:
Wolfgang Huß 2025-09-13 13:39:39 +02:00 committed by GitHub
parent ebb8ef4f0e
commit d9a7c1adc5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
13 changed files with 305 additions and 94 deletions

View File

@ -93,6 +93,8 @@ const redis = {
}
const required = {
EMAIL_DEFAULT_SENDER: env.EMAIL_DEFAULT_SENDER,
AWS_ACCESS_KEY_ID: env.AWS_ACCESS_KEY_ID,
AWS_SECRET_ACCESS_KEY: env.AWS_SECRET_ACCESS_KEY,
AWS_ENDPOINT: env.AWS_ENDPOINT,
@ -122,7 +124,6 @@ function assertRequiredConfig(
assertRequiredConfig(required)
const options = {
EMAIL_DEFAULT_SENDER: env.EMAIL_DEFAULT_SENDER,
SUPPORT_EMAIL: env.SUPPORT_EMAIL,
SUPPORT_URL: emails.SUPPORT_LINK,
APPLICATION_NAME: metadata.APPLICATION_NAME,

View File

@ -3,7 +3,10 @@
exports[`sendChatMessageMail English chat_message template 1`] = `
{
"attachments": [],
"from": "ocelot.social <devops@ocelot.social>",
"from": {
"address": "devops@ocelot.social",
"name": "ocelot.social",
},
"html": "<!DOCTYPE html>
<html lang="en">
<head>
@ -132,14 +135,20 @@ devops@ocelot.social [devops@ocelot.social]
ocelot.social Community [https://ocelot.social]",
"to": "user@example.org",
"to": {
"address": "user@example.org",
"name": "chatReceiver",
},
}
`;
exports[`sendChatMessageMail German chat_message template 1`] = `
{
"attachments": [],
"from": "ocelot.social <devops@ocelot.social>",
"from": {
"address": "devops@ocelot.social",
"name": "ocelot.social",
},
"html": "<!DOCTYPE html>
<html lang="de">
<head>
@ -268,6 +277,9 @@ devops@ocelot.social [devops@ocelot.social]
ocelot.social Community [https://ocelot.social]",
"to": "user@example.org",
"to": {
"address": "user@example.org",
"name": "chatReceiver",
},
}
`;

View File

@ -3,7 +3,10 @@
exports[`sendEmailVerification English renders correctly 1`] = `
{
"attachments": [],
"from": "ocelot.social <devops@ocelot.social>",
"from": {
"address": "devops@ocelot.social",
"name": "ocelot.social",
},
"html": "<!DOCTYPE html>
<html lang="en">
<head>
@ -135,14 +138,20 @@ devops@ocelot.social [devops@ocelot.social]
ocelot.social Community [https://ocelot.social]",
"to": "user@example.org",
"to": {
"address": "user@example.org",
"name": "User",
},
}
`;
exports[`sendEmailVerification German renders correctly 1`] = `
{
"attachments": [],
"from": "ocelot.social <devops@ocelot.social>",
"from": {
"address": "devops@ocelot.social",
"name": "ocelot.social",
},
"html": "<!DOCTYPE html>
<html lang="de">
<head>
@ -274,6 +283,9 @@ devops@ocelot.social [devops@ocelot.social]
ocelot.social Community [https://ocelot.social]",
"to": "user@example.org",
"to": {
"address": "user@example.org",
"name": "User",
},
}
`;

View File

@ -3,7 +3,10 @@
exports[`sendNotificationMail English changed_group_member_role template 1`] = `
{
"attachments": [],
"from": "ocelot.social <devops@ocelot.social>",
"from": {
"address": "devops@ocelot.social",
"name": "ocelot.social",
},
"html": "<!DOCTYPE html>
<html lang="en">
<head>
@ -131,14 +134,20 @@ devops@ocelot.social [devops@ocelot.social]
ocelot.social Community [https://ocelot.social]",
"to": "user@example.org",
"to": {
"address": "user@example.org",
"name": "Jenny Rostock",
},
}
`;
exports[`sendNotificationMail English commented_on_post template 1`] = `
{
"attachments": [],
"from": "ocelot.social <devops@ocelot.social>",
"from": {
"address": "devops@ocelot.social",
"name": "ocelot.social",
},
"html": "<!DOCTYPE html>
<html lang="en">
<head>
@ -268,14 +277,20 @@ devops@ocelot.social [devops@ocelot.social]
ocelot.social Community [https://ocelot.social]",
"to": "user@example.org",
"to": {
"address": "user@example.org",
"name": "Jenny Rostock",
},
}
`;
exports[`sendNotificationMail English followed_user_posted template 1`] = `
{
"attachments": [],
"from": "ocelot.social <devops@ocelot.social>",
"from": {
"address": "devops@ocelot.social",
"name": "ocelot.social",
},
"html": "<!DOCTYPE html>
<html lang="en">
<head>
@ -405,14 +420,20 @@ devops@ocelot.social [devops@ocelot.social]
ocelot.social Community [https://ocelot.social]",
"to": "user@example.org",
"to": {
"address": "user@example.org",
"name": "Jenny Rostock",
},
}
`;
exports[`sendNotificationMail English mentioned_in_comment template 1`] = `
{
"attachments": [],
"from": "ocelot.social <devops@ocelot.social>",
"from": {
"address": "devops@ocelot.social",
"name": "ocelot.social",
},
"html": "<!DOCTYPE html>
<html lang="en">
<head>
@ -542,14 +563,20 @@ devops@ocelot.social [devops@ocelot.social]
ocelot.social Community [https://ocelot.social]",
"to": "user@example.org",
"to": {
"address": "user@example.org",
"name": "Jenny Rostock",
},
}
`;
exports[`sendNotificationMail English mentioned_in_post template 1`] = `
{
"attachments": [],
"from": "ocelot.social <devops@ocelot.social>",
"from": {
"address": "devops@ocelot.social",
"name": "ocelot.social",
},
"html": "<!DOCTYPE html>
<html lang="en">
<head>
@ -678,14 +705,20 @@ devops@ocelot.social [devops@ocelot.social]
ocelot.social Community [https://ocelot.social]",
"to": "user@example.org",
"to": {
"address": "user@example.org",
"name": "Jenny Rostock",
},
}
`;
exports[`sendNotificationMail English post_in_group template 1`] = `
{
"attachments": [],
"from": "ocelot.social <devops@ocelot.social>",
"from": {
"address": "devops@ocelot.social",
"name": "ocelot.social",
},
"html": "<!DOCTYPE html>
<html lang="en">
<head>
@ -813,14 +846,20 @@ devops@ocelot.social [devops@ocelot.social]
ocelot.social Community [https://ocelot.social]",
"to": "user@example.org",
"to": {
"address": "user@example.org",
"name": "Jenny Rostock",
},
}
`;
exports[`sendNotificationMail English removed_user_from_group template 1`] = `
{
"attachments": [],
"from": "ocelot.social <devops@ocelot.social>",
"from": {
"address": "devops@ocelot.social",
"name": "ocelot.social",
},
"html": "<!DOCTYPE html>
<html lang="en">
<head>
@ -945,14 +984,20 @@ devops@ocelot.social [devops@ocelot.social]
ocelot.social Community [https://ocelot.social]",
"to": "user@example.org",
"to": {
"address": "user@example.org",
"name": "Jenny Rostock",
},
}
`;
exports[`sendNotificationMail English user_joined_group template 1`] = `
{
"attachments": [],
"from": "ocelot.social <devops@ocelot.social>",
"from": {
"address": "devops@ocelot.social",
"name": "ocelot.social",
},
"html": "<!DOCTYPE html>
<html lang="en">
<head>
@ -1081,14 +1126,20 @@ devops@ocelot.social [devops@ocelot.social]
ocelot.social Community [https://ocelot.social]",
"to": "user@example.org",
"to": {
"address": "user@example.org",
"name": "Jenny Rostock",
},
}
`;
exports[`sendNotificationMail English user_left_group template 1`] = `
{
"attachments": [],
"from": "ocelot.social <devops@ocelot.social>",
"from": {
"address": "devops@ocelot.social",
"name": "ocelot.social",
},
"html": "<!DOCTYPE html>
<html lang="en">
<head>
@ -1217,14 +1268,20 @@ devops@ocelot.social [devops@ocelot.social]
ocelot.social Community [https://ocelot.social]",
"to": "user@example.org",
"to": {
"address": "user@example.org",
"name": "Jenny Rostock",
},
}
`;
exports[`sendNotificationMail German changed_group_member_role template 1`] = `
{
"attachments": [],
"from": "ocelot.social <devops@ocelot.social>",
"from": {
"address": "devops@ocelot.social",
"name": "ocelot.social",
},
"html": "<!DOCTYPE html>
<html lang="de">
<head>
@ -1352,14 +1409,20 @@ devops@ocelot.social [devops@ocelot.social]
ocelot.social Community [https://ocelot.social]",
"to": "user@example.org",
"to": {
"address": "user@example.org",
"name": "Jenny Rostock",
},
}
`;
exports[`sendNotificationMail German commented_on_post template 1`] = `
{
"attachments": [],
"from": "ocelot.social <devops@ocelot.social>",
"from": {
"address": "devops@ocelot.social",
"name": "ocelot.social",
},
"html": "<!DOCTYPE html>
<html lang="de">
<head>
@ -1489,14 +1552,20 @@ devops@ocelot.social [devops@ocelot.social]
ocelot.social Community [https://ocelot.social]",
"to": "user@example.org",
"to": {
"address": "user@example.org",
"name": "Jenny Rostock",
},
}
`;
exports[`sendNotificationMail German followed_user_posted template 1`] = `
{
"attachments": [],
"from": "ocelot.social <devops@ocelot.social>",
"from": {
"address": "devops@ocelot.social",
"name": "ocelot.social",
},
"html": "<!DOCTYPE html>
<html lang="de">
<head>
@ -1626,14 +1695,20 @@ devops@ocelot.social [devops@ocelot.social]
ocelot.social Community [https://ocelot.social]",
"to": "user@example.org",
"to": {
"address": "user@example.org",
"name": "Jenny Rostock",
},
}
`;
exports[`sendNotificationMail German mentioned_in_comment template 1`] = `
{
"attachments": [],
"from": "ocelot.social <devops@ocelot.social>",
"from": {
"address": "devops@ocelot.social",
"name": "ocelot.social",
},
"html": "<!DOCTYPE html>
<html lang="de">
<head>
@ -1763,14 +1838,20 @@ devops@ocelot.social [devops@ocelot.social]
ocelot.social Community [https://ocelot.social]",
"to": "user@example.org",
"to": {
"address": "user@example.org",
"name": "Jenny Rostock",
},
}
`;
exports[`sendNotificationMail German mentioned_in_post template 1`] = `
{
"attachments": [],
"from": "ocelot.social <devops@ocelot.social>",
"from": {
"address": "devops@ocelot.social",
"name": "ocelot.social",
},
"html": "<!DOCTYPE html>
<html lang="de">
<head>
@ -1900,14 +1981,20 @@ devops@ocelot.social [devops@ocelot.social]
ocelot.social Community [https://ocelot.social]",
"to": "user@example.org",
"to": {
"address": "user@example.org",
"name": "Jenny Rostock",
},
}
`;
exports[`sendNotificationMail German post_in_group template 1`] = `
{
"attachments": [],
"from": "ocelot.social <devops@ocelot.social>",
"from": {
"address": "devops@ocelot.social",
"name": "ocelot.social",
},
"html": "<!DOCTYPE html>
<html lang="de">
<head>
@ -2035,14 +2122,20 @@ devops@ocelot.social [devops@ocelot.social]
ocelot.social Community [https://ocelot.social]",
"to": "user@example.org",
"to": {
"address": "user@example.org",
"name": "Jenny Rostock",
},
}
`;
exports[`sendNotificationMail German removed_user_from_group template 1`] = `
{
"attachments": [],
"from": "ocelot.social <devops@ocelot.social>",
"from": {
"address": "devops@ocelot.social",
"name": "ocelot.social",
},
"html": "<!DOCTYPE html>
<html lang="de">
<head>
@ -2167,14 +2260,20 @@ devops@ocelot.social [devops@ocelot.social]
ocelot.social Community [https://ocelot.social]",
"to": "user@example.org",
"to": {
"address": "user@example.org",
"name": "Jenny Rostock",
},
}
`;
exports[`sendNotificationMail German user_joined_group template 1`] = `
{
"attachments": [],
"from": "ocelot.social <devops@ocelot.social>",
"from": {
"address": "devops@ocelot.social",
"name": "ocelot.social",
},
"html": "<!DOCTYPE html>
<html lang="de">
<head>
@ -2303,14 +2402,20 @@ devops@ocelot.social [devops@ocelot.social]
ocelot.social Community [https://ocelot.social]",
"to": "user@example.org",
"to": {
"address": "user@example.org",
"name": "Jenny Rostock",
},
}
`;
exports[`sendNotificationMail German user_left_group template 1`] = `
{
"attachments": [],
"from": "ocelot.social <devops@ocelot.social>",
"from": {
"address": "devops@ocelot.social",
"name": "ocelot.social",
},
"html": "<!DOCTYPE html>
<html lang="de">
<head>
@ -2439,6 +2544,9 @@ devops@ocelot.social [devops@ocelot.social]
ocelot.social Community [https://ocelot.social]",
"to": "user@example.org",
"to": {
"address": "user@example.org",
"name": "Jenny Rostock",
},
}
`;

View File

@ -3,7 +3,10 @@
exports[`sendRegistrationMail with invite code English renders correctly 1`] = `
{
"attachments": [],
"from": "ocelot.social <devops@ocelot.social>",
"from": {
"address": "devops@ocelot.social",
"name": "ocelot.social",
},
"html": "<!DOCTYPE html>
<html lang="en">
<head>
@ -94,7 +97,7 @@ footer {
<h2>Welcome to ocelot.social!</h2>
<div class="wrapper">
<div class="content"></div>
<p>Thank you for joining our cause it's awesome to have you on board. There's just one tiny step missing before we can start shaping the world together … Please confirm your e-mail address by clicking the button below:</p><a class="button" href="http://webapp:3000/registration?email=user%40example.org&amp;nonce=123456&amp;inviteCode=welcome&amp;method=invite-code">Confirm your e-mail address</a>
<p>Thank you for joining our cause it's awesome to have you on board. There's just one tiny step missing before we can start shaping the world together … Please confirm your e-mail address by clicking the button below:</p><a class="button" href="http://webapp:3000/registration?email=moderator%40example.org&amp;nonce=123456&amp;inviteCode=welcome&amp;method=invite-code">Confirm your e-mail address</a>
<p>If the above button doesn't work, you can also copy the following code into your browser window: <span>123456</span></p>
<p>However, this only works if you have registered through our website.</p>
<p>If you didn't sign up for <a>ocelot.social</a> we recommend you to check it out! It's a social network from people for people who want to connect and change the world together.
@ -122,7 +125,7 @@ just one tiny step missing before we can start shaping the world together …
Please confirm your e-mail address by clicking the button below:
Confirm your e-mail address
[http://webapp:3000/registration?email=user%40example.org&nonce=123456&inviteCode=welcome&method=invite-code]
[http://webapp:3000/registration?email=moderator%40example.org&nonce=123456&inviteCode=welcome&method=invite-code]
If the above button doesn't work, you can also copy the following code into your
browser window: 123456
@ -144,14 +147,20 @@ devops@ocelot.social [devops@ocelot.social]
ocelot.social Community [https://ocelot.social]",
"to": "user@example.org",
"to": {
"address": "moderator@example.org",
"name": "Bob &"?@\\ Baumeister",
},
}
`;
exports[`sendRegistrationMail with invite code German renders correctly 1`] = `
{
"attachments": [],
"from": "ocelot.social <devops@ocelot.social>",
"from": {
"address": "devops@ocelot.social",
"name": "ocelot.social",
},
"html": "<!DOCTYPE html>
<html lang="de">
<head>
@ -242,7 +251,7 @@ footer {
<h2>Willkommen bei ocelot.social!</h2>
<div class="wrapper">
<div class="content"></div>
<p>Danke, dass du dich angemeldet hast wir freuen uns, dich dabei zu haben. Jetzt fehlt nur noch eine Kleinigkeit, bevor wir gemeinsam die Welt verbessern können … Bitte bestätige deine E-Mail Adresse:</p><a class="button" href="http://webapp:3000/registration?email=user%40example.org&amp;nonce=123456&amp;inviteCode=welcome&amp;method=invite-code">Bestätige deine E-Mail Adresse</a>
<p>Danke, dass du dich angemeldet hast wir freuen uns, dich dabei zu haben. Jetzt fehlt nur noch eine Kleinigkeit, bevor wir gemeinsam die Welt verbessern können … Bitte bestätige deine E-Mail Adresse:</p><a class="button" href="http://webapp:3000/registration?email=moderator%40example.org&amp;nonce=123456&amp;inviteCode=welcome&amp;method=invite-code">Bestätige deine E-Mail Adresse</a>
<p>Sollte der Button für dich nicht funktionieren, kannst du auch folgenden Code in dein Browserfenster kopieren: <span>123456</span></p>
<p>Das funktioniert allerdings nur, wenn du dich über unsere Website registriert hast.</p>
<p>Falls du dich nicht selbst bei <a>ocelot.social</a> angemeldet hast, schau doch mal vorbei! Wir sind ein gemeinnütziges Aktionsnetzwerk von Menschen für Menschen.
@ -270,7 +279,7 @@ fehlt nur noch eine Kleinigkeit, bevor wir gemeinsam die Welt verbessern können
… Bitte bestätige deine E-Mail Adresse:
Bestätige deine E-Mail Adresse
[http://webapp:3000/registration?email=user%40example.org&nonce=123456&inviteCode=welcome&method=invite-code]
[http://webapp:3000/registration?email=moderator%40example.org&nonce=123456&inviteCode=welcome&method=invite-code]
Sollte der Button für dich nicht funktionieren, kannst du auch folgenden Code in
dein Browserfenster kopieren: 123456
@ -293,14 +302,20 @@ devops@ocelot.social [devops@ocelot.social]
ocelot.social Community [https://ocelot.social]",
"to": "user@example.org",
"to": {
"address": "moderator@example.org",
"name": "Bob &"?@\\ Baumeister",
},
}
`;
exports[`sendRegistrationMail without invite code English renders correctly 1`] = `
{
"attachments": [],
"from": "ocelot.social <devops@ocelot.social>",
"from": {
"address": "devops@ocelot.social",
"name": "ocelot.social",
},
"html": "<!DOCTYPE html>
<html lang="en">
<head>
@ -391,7 +406,7 @@ footer {
<h2>Welcome to ocelot.social!</h2>
<div class="wrapper">
<div class="content"></div>
<p>Thank you for joining our cause it's awesome to have you on board. There's just one tiny step missing before we can start shaping the world together … Please confirm your e-mail address by clicking the button below:</p><a class="button" href="http://webapp:3000/registration?email=user%40example.org&amp;nonce=123456&amp;method=invite-mail">Confirm your e-mail address</a>
<p>Thank you for joining our cause it's awesome to have you on board. There's just one tiny step missing before we can start shaping the world together … Please confirm your e-mail address by clicking the button below:</p><a class="button" href="http://webapp:3000/registration?email=moderator%40example.org&amp;nonce=123456&amp;method=invite-mail">Confirm your e-mail address</a>
<p>If the above button doesn't work, you can also copy the following code into your browser window: <span>123456</span></p>
<p>However, this only works if you have registered through our website.</p>
<p>If you didn't sign up for <a>ocelot.social</a> we recommend you to check it out! It's a social network from people for people who want to connect and change the world together.
@ -419,7 +434,7 @@ just one tiny step missing before we can start shaping the world together …
Please confirm your e-mail address by clicking the button below:
Confirm your e-mail address
[http://webapp:3000/registration?email=user%40example.org&nonce=123456&method=invite-mail]
[http://webapp:3000/registration?email=moderator%40example.org&nonce=123456&method=invite-mail]
If the above button doesn't work, you can also copy the following code into your
browser window: 123456
@ -441,14 +456,20 @@ devops@ocelot.social [devops@ocelot.social]
ocelot.social Community [https://ocelot.social]",
"to": "user@example.org",
"to": {
"address": "moderator@example.org",
"name": "Bob &"?@\\ Baumeister",
},
}
`;
exports[`sendRegistrationMail without invite code German renders correctly 1`] = `
{
"attachments": [],
"from": "ocelot.social <devops@ocelot.social>",
"from": {
"address": "devops@ocelot.social",
"name": "ocelot.social",
},
"html": "<!DOCTYPE html>
<html lang="de">
<head>
@ -539,7 +560,7 @@ footer {
<h2>Willkommen bei ocelot.social!</h2>
<div class="wrapper">
<div class="content"></div>
<p>Danke, dass du dich angemeldet hast wir freuen uns, dich dabei zu haben. Jetzt fehlt nur noch eine Kleinigkeit, bevor wir gemeinsam die Welt verbessern können … Bitte bestätige deine E-Mail Adresse:</p><a class="button" href="http://webapp:3000/registration?email=user%40example.org&amp;nonce=123456&amp;method=invite-mail">Bestätige deine E-Mail Adresse</a>
<p>Danke, dass du dich angemeldet hast wir freuen uns, dich dabei zu haben. Jetzt fehlt nur noch eine Kleinigkeit, bevor wir gemeinsam die Welt verbessern können … Bitte bestätige deine E-Mail Adresse:</p><a class="button" href="http://webapp:3000/registration?email=moderator%40example.org&amp;nonce=123456&amp;method=invite-mail">Bestätige deine E-Mail Adresse</a>
<p>Sollte der Button für dich nicht funktionieren, kannst du auch folgenden Code in dein Browserfenster kopieren: <span>123456</span></p>
<p>Das funktioniert allerdings nur, wenn du dich über unsere Website registriert hast.</p>
<p>Falls du dich nicht selbst bei <a>ocelot.social</a> angemeldet hast, schau doch mal vorbei! Wir sind ein gemeinnütziges Aktionsnetzwerk von Menschen für Menschen.
@ -567,7 +588,7 @@ fehlt nur noch eine Kleinigkeit, bevor wir gemeinsam die Welt verbessern können
… Bitte bestätige deine E-Mail Adresse:
Bestätige deine E-Mail Adresse
[http://webapp:3000/registration?email=user%40example.org&nonce=123456&method=invite-mail]
[http://webapp:3000/registration?email=moderator%40example.org&nonce=123456&method=invite-mail]
Sollte der Button für dich nicht funktionieren, kannst du auch folgenden Code in
dein Browserfenster kopieren: 123456
@ -590,6 +611,9 @@ devops@ocelot.social [devops@ocelot.social]
ocelot.social Community [https://ocelot.social]",
"to": "user@example.org",
"to": {
"address": "moderator@example.org",
"name": "Bob &"?@\\ Baumeister",
},
}
`;

View File

@ -3,7 +3,10 @@
exports[`sendResetPasswordMail English renders correctly 1`] = `
{
"attachments": [],
"from": "ocelot.social <devops@ocelot.social>",
"from": {
"address": "devops@ocelot.social",
"name": "ocelot.social",
},
"html": "<!DOCTYPE html>
<html lang="en">
<head>
@ -134,14 +137,20 @@ devops@ocelot.social [devops@ocelot.social]
ocelot.social Community [https://ocelot.social]",
"to": "user@example.org",
"to": {
"address": "user@example.org",
"name": "Jenny Rostock",
},
}
`;
exports[`sendResetPasswordMail German renders correctly 1`] = `
{
"attachments": [],
"from": "ocelot.social <devops@ocelot.social>",
"from": {
"address": "devops@ocelot.social",
"name": "ocelot.social",
},
"html": "<!DOCTYPE html>
<html lang="de">
<head>
@ -273,6 +282,9 @@ devops@ocelot.social [devops@ocelot.social]
ocelot.social Community [https://ocelot.social]",
"to": "user@example.org",
"to": {
"address": "user@example.org",
"name": "Jenny Rostock",
},
}
`;

View File

@ -3,7 +3,10 @@
exports[`sendWrongEmail English renders correctly 1`] = `
{
"attachments": [],
"from": "ocelot.social <devops@ocelot.social>",
"from": {
"address": "devops@ocelot.social",
"name": "ocelot.social",
},
"html": "<!DOCTYPE html>
<html lang="en">
<head>
@ -132,14 +135,20 @@ devops@ocelot.social [devops@ocelot.social]
ocelot.social Community [https://ocelot.social]",
"to": "user@example.org",
"to": {
"address": "moderator@example.org",
"name": "Bob &"?@\\ Baumeister",
},
}
`;
exports[`sendWrongEmail German renders correctly 1`] = `
{
"attachments": [],
"from": "ocelot.social <devops@ocelot.social>",
"from": {
"address": "devops@ocelot.social",
"name": "ocelot.social",
},
"html": "<!DOCTYPE html>
<html lang="de">
<head>
@ -268,6 +277,9 @@ devops@ocelot.social [devops@ocelot.social]
ocelot.social Community [https://ocelot.social]",
"to": "user@example.org",
"to": {
"address": "moderator@example.org",
"name": "Bob &"?@\\ Baumeister",
},
}
`;

View File

@ -3,7 +3,10 @@
exports[`sendResetPasswordMail with support English renders correctly 1`] = `
{
"attachments": [],
"from": "ocelot.social <devops@ocelot.social>",
"from": {
"address": "devops@ocelot.social",
"name": "ocelot.social",
},
"html": "<!DOCTYPE html>
<html lang="en">
<head>
@ -134,14 +137,20 @@ support@example.org [support@example.org]
ocelot.social Community [https://ocelot.social]",
"to": "user@example.org",
"to": {
"address": "user@example.org",
"name": "Jenny Rostock",
},
}
`;
exports[`sendResetPasswordMail with support German renders correctly 1`] = `
{
"attachments": [],
"from": "ocelot.social <devops@ocelot.social>",
"from": {
"address": "devops@ocelot.social",
"name": "ocelot.social",
},
"html": "<!DOCTYPE html>
<html lang="de">
<head>
@ -273,14 +282,20 @@ support@example.org [support@example.org]
ocelot.social Community [https://ocelot.social]",
"to": "user@example.org",
"to": {
"address": "user@example.org",
"name": "Jenny Rostock",
},
}
`;
exports[`sendResetPasswordMail without support English renders correctly 1`] = `
{
"attachments": [],
"from": "ocelot.social <devops@ocelot.social>",
"from": {
"address": "devops@ocelot.social",
"name": "ocelot.social",
},
"html": "<!DOCTYPE html>
<html lang="en">
<head>
@ -405,14 +420,20 @@ See you soon on ocelot.social [https://ocelot.social]!
ocelot.social Community [https://ocelot.social]",
"to": "user@example.org",
"to": {
"address": "user@example.org",
"name": "Jenny Rostock",
},
}
`;
exports[`sendResetPasswordMail without support German renders correctly 1`] = `
{
"attachments": [],
"from": "ocelot.social <devops@ocelot.social>",
"from": {
"address": "devops@ocelot.social",
"name": "ocelot.social",
},
"html": "<!DOCTYPE html>
<html lang="de">
<head>
@ -538,6 +559,9 @@ Bis bald bei ocelot.social [https://ocelot.social]!
ocelot.social Community [https://ocelot.social]",
"to": "user@example.org",
"to": {
"address": "user@example.org",
"name": "Jenny Rostock",
},
}
`;

View File

@ -29,7 +29,7 @@ export const defaultParams = {
renderSettingsUrl: true,
}
const from = `${CONFIG.APPLICATION_NAME} <${CONFIG.EMAIL_DEFAULT_SENDER}>`
const from = { name: CONFIG.APPLICATION_NAME, address: CONFIG.EMAIL_DEFAULT_SENDER }
const transport = createTransport(nodemailerTransportOptions)
@ -74,8 +74,8 @@ interface OriginalMessage {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export const sendNotificationMail = async (notification: any): Promise<OriginalMessage> => {
const locale = notification?.to?.locale
const to = notification?.email
const name = notification?.to?.name
const to = { name, address: notification?.email }
const template = notification?.reason
try {
@ -165,7 +165,7 @@ export const sendChatMessageMail = async (
data: ChatMessageEmailInput,
): Promise<OriginalMessage> => {
const { senderUser, recipientUser } = data
const to = data.email
const to = { name: recipientUser.name, address: data.email }
try {
const { originalMessage } = await email.send({
template: path.join(__dirname, 'templates', 'chat_message'),
@ -188,6 +188,7 @@ export const sendChatMessageMail = async (
}
interface VerifyMailInput {
name: string
email: string
nonce: string
locale: string
@ -200,10 +201,10 @@ interface RegistrationMailInput extends VerifyMailInput {
export const sendRegistrationMail = async (
data: RegistrationMailInput,
): Promise<OriginalMessage> => {
const { nonce, locale, inviteCode } = data
const to = data.email
const { name, nonce, locale, inviteCode } = data
const to = { name, address: data.email }
const actionUrl = new URL('/registration', CONFIG.CLIENT_URI)
actionUrl.searchParams.set('email', to)
actionUrl.searchParams.set('email', to.address)
actionUrl.searchParams.set('nonce', nonce)
if (inviteCode) {
actionUrl.searchParams.set('inviteCode', inviteCode)
@ -240,9 +241,9 @@ export const sendEmailVerification = async (
data: EmailVerificationInput,
): Promise<OriginalMessage> => {
const { nonce, locale, name } = data
const to = data.email
const to = { name, address: data.email }
const actionUrl = new URL('/settings/my-email-address/verify', CONFIG.CLIENT_URI)
actionUrl.searchParams.set('email', to)
actionUrl.searchParams.set('email', to.address)
actionUrl.searchParams.set('nonce', nonce)
try {
@ -270,9 +271,9 @@ export const sendResetPasswordMail = async (
data: EmailVerificationInput,
): Promise<OriginalMessage> => {
const { nonce, locale, name } = data
const to = data.email
const to = { name, address: data.email }
const actionUrl = new URL('/password-reset/change-password', CONFIG.CLIENT_URI)
actionUrl.searchParams.set('email', to)
actionUrl.searchParams.set('email', to.address)
actionUrl.searchParams.set('nonce', nonce)
try {
const { originalMessage } = await email.send({
@ -296,11 +297,12 @@ export const sendResetPasswordMail = async (
}
export const sendWrongEmail = async (data: {
name: string
locale: string
email: string
}): Promise<OriginalMessage> => {
const { locale } = data
const to = data.email
const { locale, name } = data
const to = { name, address: data.email }
const actionUrl = new URL('/password-reset/request', CONFIG.CLIENT_URI)
try {
const { originalMessage } = await email.send({

View File

@ -7,12 +7,14 @@ import { sendRegistrationMail } from './sendEmail'
describe('sendRegistrationMail', () => {
const data: {
name: string
email: string
nonce: string
locale: string
inviteCode?: string
} = {
email: 'user@example.org',
name: 'Bob &"?@\\ Baumeister',
email: 'moderator@example.org',
nonce: '123456',
locale: 'en',
inviteCode: 'welcome',

View File

@ -7,10 +7,12 @@ import { sendWrongEmail } from './sendEmail'
describe('sendWrongEmail', () => {
const data: {
name: string
email: string
locale: string
} = {
email: 'user@example.org',
name: 'Bob &"?@\\ Baumeister',
email: 'moderator@example.org',
locale: 'en',
}

View File

@ -1 +1 @@
= `${APPLICATION_NAME} ${t('notification')}: ${t('subjects.removedUserFromGroup')}`
!= `${APPLICATION_NAME} ${t('notification')}: ${t('subjects.removedUserFromGroup')}`

View File

@ -11,10 +11,10 @@ import {
const sendSignupMail = async (resolve, root, args, context, resolveInfo) => {
const { inviteCode, locale } = args
const response = await resolve(root, args, context, resolveInfo)
const { email, nonce } = response
const { name, email, nonce } = response
if (nonce) {
// emails that already exist do not have a nonce
await sendRegistrationMail({ email, nonce, locale, inviteCode })
await sendRegistrationMail({ name, email, nonce, locale, inviteCode })
}
delete response.nonce
return response