mirror of
https://github.com/Ocelot-Social-Community/Ocelot-Social.git
synced 2025-12-12 23:35:58 +00:00
feat(backend): signup email localized (#8459)
* localized registration email * localized email verification email * localized reset password email
This commit is contained in:
parent
63dd215297
commit
65f764f6d9
@ -62,6 +62,10 @@ a.button {
|
|||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
color: #17b53e;
|
||||||
|
}
|
||||||
|
|
||||||
.text-block {
|
.text-block {
|
||||||
margin-top: 20px;
|
margin-top: 20px;
|
||||||
color: #000000;
|
color: #000000;
|
||||||
@ -185,6 +189,10 @@ a.button {
|
|||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
color: #17b53e;
|
||||||
|
}
|
||||||
|
|
||||||
.text-block {
|
.text-block {
|
||||||
margin-top: 20px;
|
margin-top: 20px;
|
||||||
color: #000000;
|
color: #000000;
|
||||||
|
|||||||
@ -0,0 +1,261 @@
|
|||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`sendEmailVerification English renders correctly 1`] = `
|
||||||
|
{
|
||||||
|
"attachments": [],
|
||||||
|
"from": "ocelot.social",
|
||||||
|
"html": "<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta content="multipart/html; charset=UTF-8" http-equiv="content-type">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<style>.wf-force-outline-none[tabindex="-1"]:focus{outline:none;}</style>
|
||||||
|
<style>body{
|
||||||
|
display: block;
|
||||||
|
font-family: Lato, sans-serif;
|
||||||
|
font-size: 17px;
|
||||||
|
text-align: left;
|
||||||
|
text-align: -webkit-left;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 15px;
|
||||||
|
margin: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
margin-top: 25px;
|
||||||
|
font-size: 25px;
|
||||||
|
font-weight: normal;
|
||||||
|
line-height: 22px;
|
||||||
|
color: #333333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
max-width: 680px;
|
||||||
|
margin: 0 auto;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.head-logo {
|
||||||
|
width: 60%;
|
||||||
|
height: auto;
|
||||||
|
display: block;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: #17b53e;
|
||||||
|
}
|
||||||
|
|
||||||
|
a.button {
|
||||||
|
background: #17b53e;
|
||||||
|
font-family: Lato, sans-serif;
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 15px;
|
||||||
|
text-decoration: none;
|
||||||
|
text-align:center;
|
||||||
|
padding: 13px 17px;
|
||||||
|
color: #ffffff;
|
||||||
|
display: table;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
color: #17b53e;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-block {
|
||||||
|
margin-top: 20px;
|
||||||
|
color: #000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
footer {
|
||||||
|
padding: 20px;
|
||||||
|
font-family: Lato, sans-serif;
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 15px;
|
||||||
|
text-align: center;
|
||||||
|
color: #888888;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<header>
|
||||||
|
<div class="head"><img class="head-logo" alt="Welcome Image" loading="lazy" src="http://webapp:3000/img/custom/logo-squared.svg">
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
<h2>Hello User,</h2>
|
||||||
|
<div class="wrapper">
|
||||||
|
<div class="content"></div>
|
||||||
|
<p>So, you want to change your e-mail? No problem! Just click the button below to verify your new address:</p><a class="button" href="http://webapp:3000/settings/my-email-address/verify?email=user%40example.org&nonce=123456">Verify e-mail address</a>
|
||||||
|
<p>If you don't want to change your e-mail address feel free to ignore this message. </p>
|
||||||
|
<p>If the above button doesn't work, you can also copy the following code into your browser window: <span>123456</span></p>
|
||||||
|
<div class="text-block">
|
||||||
|
<p>See you soon on <a class="organization" href="https://ocelot.social">ocelot.social</a>!</p>
|
||||||
|
<p>– The ocelot.social Team</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<footer>
|
||||||
|
<div class="footer"></div><a href="https://ocelot.social">ocelot.social Community</a>
|
||||||
|
</footer>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>",
|
||||||
|
"subject": "New E-Mail Address ocelot.social",
|
||||||
|
"text": "HELLO USER,
|
||||||
|
|
||||||
|
So, you want to change your e-mail? No problem! Just click the button below to
|
||||||
|
verify your new address:
|
||||||
|
|
||||||
|
Verify e-mail address
|
||||||
|
[http://webapp:3000/settings/my-email-address/verify?email=user%40example.org&nonce=123456]
|
||||||
|
|
||||||
|
If you don't want to change your e-mail address feel free to ignore this
|
||||||
|
message.
|
||||||
|
|
||||||
|
If the above button doesn't work, you can also copy the following code into your
|
||||||
|
browser window: 123456
|
||||||
|
|
||||||
|
See you soon on ocelot.social [https://ocelot.social]!
|
||||||
|
|
||||||
|
– The ocelot.social Team
|
||||||
|
|
||||||
|
|
||||||
|
ocelot.social Community [https://ocelot.social]",
|
||||||
|
"to": "user@example.org",
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`sendEmailVerification German renders correctly 1`] = `
|
||||||
|
{
|
||||||
|
"attachments": [],
|
||||||
|
"from": "ocelot.social",
|
||||||
|
"html": "<!DOCTYPE html>
|
||||||
|
<html lang="de">
|
||||||
|
<head>
|
||||||
|
<meta content="multipart/html; charset=UTF-8" http-equiv="content-type">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<style>.wf-force-outline-none[tabindex="-1"]:focus{outline:none;}</style>
|
||||||
|
<style>body{
|
||||||
|
display: block;
|
||||||
|
font-family: Lato, sans-serif;
|
||||||
|
font-size: 17px;
|
||||||
|
text-align: left;
|
||||||
|
text-align: -webkit-left;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 15px;
|
||||||
|
margin: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
margin-top: 25px;
|
||||||
|
font-size: 25px;
|
||||||
|
font-weight: normal;
|
||||||
|
line-height: 22px;
|
||||||
|
color: #333333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
max-width: 680px;
|
||||||
|
margin: 0 auto;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.head-logo {
|
||||||
|
width: 60%;
|
||||||
|
height: auto;
|
||||||
|
display: block;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: #17b53e;
|
||||||
|
}
|
||||||
|
|
||||||
|
a.button {
|
||||||
|
background: #17b53e;
|
||||||
|
font-family: Lato, sans-serif;
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 15px;
|
||||||
|
text-decoration: none;
|
||||||
|
text-align:center;
|
||||||
|
padding: 13px 17px;
|
||||||
|
color: #ffffff;
|
||||||
|
display: table;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
color: #17b53e;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-block {
|
||||||
|
margin-top: 20px;
|
||||||
|
color: #000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
footer {
|
||||||
|
padding: 20px;
|
||||||
|
font-family: Lato, sans-serif;
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 15px;
|
||||||
|
text-align: center;
|
||||||
|
color: #888888;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<header>
|
||||||
|
<div class="head"><img class="head-logo" alt="Welcome Image" loading="lazy" src="http://webapp:3000/img/custom/logo-squared.svg">
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
<h2>Hallo User,</h2>
|
||||||
|
<div class="wrapper">
|
||||||
|
<div class="content"></div>
|
||||||
|
<p>Du möchtest also deine E-Mail ändern? Kein Problem! Mit Klick auf diesen Button kannst Du Deine neue E-Mail Adresse bestätigen:</p><a class="button" href="http://webapp:3000/settings/my-email-address/verify?email=user%40example.org&nonce=123456">E-Mail Adresse bestätigen</a>
|
||||||
|
<p>Falls Du deine E-Mail Adresse doch nicht ändern möchtest, kannst du diese Nachricht einfach ignorieren. </p>
|
||||||
|
<p>Sollte der Button für Dich nicht funktionieren, kannst Du auch folgenden Code in Dein Browserfenster kopieren: <span>123456</span></p>
|
||||||
|
<div class="text-block">
|
||||||
|
<p>Bis bald bei <a class="organization" href="https://ocelot.social">ocelot.social</a>!</p>
|
||||||
|
<p>– Dein ocelot.social Team</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<footer>
|
||||||
|
<div class="footer"></div><a href="https://ocelot.social">ocelot.social Community</a>
|
||||||
|
</footer>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>",
|
||||||
|
"subject": "Neue E-Mail Addresse ocelot.social",
|
||||||
|
"text": "HALLO USER,
|
||||||
|
|
||||||
|
Du möchtest also deine E-Mail ändern? Kein Problem! Mit Klick auf diesen Button
|
||||||
|
kannst Du Deine neue E-Mail Adresse bestätigen:
|
||||||
|
|
||||||
|
E-Mail Adresse bestätigen
|
||||||
|
[http://webapp:3000/settings/my-email-address/verify?email=user%40example.org&nonce=123456]
|
||||||
|
|
||||||
|
Falls Du deine E-Mail Adresse doch nicht ändern möchtest, kannst du diese
|
||||||
|
Nachricht einfach ignorieren.
|
||||||
|
|
||||||
|
Sollte der Button für Dich nicht funktionieren, kannst Du auch folgenden Code in
|
||||||
|
Dein Browserfenster kopieren: 123456
|
||||||
|
|
||||||
|
Bis bald bei ocelot.social [https://ocelot.social]!
|
||||||
|
|
||||||
|
– Dein ocelot.social Team
|
||||||
|
|
||||||
|
|
||||||
|
ocelot.social Community [https://ocelot.social]",
|
||||||
|
"to": "user@example.org",
|
||||||
|
}
|
||||||
|
`;
|
||||||
@ -62,6 +62,10 @@ a.button {
|
|||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
color: #17b53e;
|
||||||
|
}
|
||||||
|
|
||||||
.text-block {
|
.text-block {
|
||||||
margin-top: 20px;
|
margin-top: 20px;
|
||||||
color: #000000;
|
color: #000000;
|
||||||
@ -184,6 +188,10 @@ a.button {
|
|||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
color: #17b53e;
|
||||||
|
}
|
||||||
|
|
||||||
.text-block {
|
.text-block {
|
||||||
margin-top: 20px;
|
margin-top: 20px;
|
||||||
color: #000000;
|
color: #000000;
|
||||||
@ -308,6 +316,10 @@ a.button {
|
|||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
color: #17b53e;
|
||||||
|
}
|
||||||
|
|
||||||
.text-block {
|
.text-block {
|
||||||
margin-top: 20px;
|
margin-top: 20px;
|
||||||
color: #000000;
|
color: #000000;
|
||||||
@ -432,6 +444,10 @@ a.button {
|
|||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
color: #17b53e;
|
||||||
|
}
|
||||||
|
|
||||||
.text-block {
|
.text-block {
|
||||||
margin-top: 20px;
|
margin-top: 20px;
|
||||||
color: #000000;
|
color: #000000;
|
||||||
@ -556,6 +572,10 @@ a.button {
|
|||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
color: #17b53e;
|
||||||
|
}
|
||||||
|
|
||||||
.text-block {
|
.text-block {
|
||||||
margin-top: 20px;
|
margin-top: 20px;
|
||||||
color: #000000;
|
color: #000000;
|
||||||
@ -679,6 +699,10 @@ a.button {
|
|||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
color: #17b53e;
|
||||||
|
}
|
||||||
|
|
||||||
.text-block {
|
.text-block {
|
||||||
margin-top: 20px;
|
margin-top: 20px;
|
||||||
color: #000000;
|
color: #000000;
|
||||||
@ -801,6 +825,10 @@ a.button {
|
|||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
color: #17b53e;
|
||||||
|
}
|
||||||
|
|
||||||
.text-block {
|
.text-block {
|
||||||
margin-top: 20px;
|
margin-top: 20px;
|
||||||
color: #000000;
|
color: #000000;
|
||||||
@ -920,6 +948,10 @@ a.button {
|
|||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
color: #17b53e;
|
||||||
|
}
|
||||||
|
|
||||||
.text-block {
|
.text-block {
|
||||||
margin-top: 20px;
|
margin-top: 20px;
|
||||||
color: #000000;
|
color: #000000;
|
||||||
@ -1043,6 +1075,10 @@ a.button {
|
|||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
color: #17b53e;
|
||||||
|
}
|
||||||
|
|
||||||
.text-block {
|
.text-block {
|
||||||
margin-top: 20px;
|
margin-top: 20px;
|
||||||
color: #000000;
|
color: #000000;
|
||||||
@ -1166,6 +1202,10 @@ a.button {
|
|||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
color: #17b53e;
|
||||||
|
}
|
||||||
|
|
||||||
.text-block {
|
.text-block {
|
||||||
margin-top: 20px;
|
margin-top: 20px;
|
||||||
color: #000000;
|
color: #000000;
|
||||||
@ -1288,6 +1328,10 @@ a.button {
|
|||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
color: #17b53e;
|
||||||
|
}
|
||||||
|
|
||||||
.text-block {
|
.text-block {
|
||||||
margin-top: 20px;
|
margin-top: 20px;
|
||||||
color: #000000;
|
color: #000000;
|
||||||
@ -1412,6 +1456,10 @@ a.button {
|
|||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
color: #17b53e;
|
||||||
|
}
|
||||||
|
|
||||||
.text-block {
|
.text-block {
|
||||||
margin-top: 20px;
|
margin-top: 20px;
|
||||||
color: #000000;
|
color: #000000;
|
||||||
@ -1536,6 +1584,10 @@ a.button {
|
|||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
color: #17b53e;
|
||||||
|
}
|
||||||
|
|
||||||
.text-block {
|
.text-block {
|
||||||
margin-top: 20px;
|
margin-top: 20px;
|
||||||
color: #000000;
|
color: #000000;
|
||||||
@ -1660,6 +1712,10 @@ a.button {
|
|||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
color: #17b53e;
|
||||||
|
}
|
||||||
|
|
||||||
.text-block {
|
.text-block {
|
||||||
margin-top: 20px;
|
margin-top: 20px;
|
||||||
color: #000000;
|
color: #000000;
|
||||||
@ -1783,6 +1839,10 @@ a.button {
|
|||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
color: #17b53e;
|
||||||
|
}
|
||||||
|
|
||||||
.text-block {
|
.text-block {
|
||||||
margin-top: 20px;
|
margin-top: 20px;
|
||||||
color: #000000;
|
color: #000000;
|
||||||
@ -1905,6 +1965,10 @@ a.button {
|
|||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
color: #17b53e;
|
||||||
|
}
|
||||||
|
|
||||||
.text-block {
|
.text-block {
|
||||||
margin-top: 20px;
|
margin-top: 20px;
|
||||||
color: #000000;
|
color: #000000;
|
||||||
@ -2024,6 +2088,10 @@ a.button {
|
|||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
color: #17b53e;
|
||||||
|
}
|
||||||
|
|
||||||
.text-block {
|
.text-block {
|
||||||
margin-top: 20px;
|
margin-top: 20px;
|
||||||
color: #000000;
|
color: #000000;
|
||||||
@ -2147,6 +2215,10 @@ a.button {
|
|||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
color: #17b53e;
|
||||||
|
}
|
||||||
|
|
||||||
.text-block {
|
.text-block {
|
||||||
margin-top: 20px;
|
margin-top: 20px;
|
||||||
color: #000000;
|
color: #000000;
|
||||||
|
|||||||
@ -0,0 +1,559 @@
|
|||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`sendRegistrationMail with invite code English renders correctly 1`] = `
|
||||||
|
{
|
||||||
|
"attachments": [],
|
||||||
|
"from": "ocelot.social",
|
||||||
|
"html": "<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta content="multipart/html; charset=UTF-8" http-equiv="content-type">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<style>.wf-force-outline-none[tabindex="-1"]:focus{outline:none;}</style>
|
||||||
|
<style>body{
|
||||||
|
display: block;
|
||||||
|
font-family: Lato, sans-serif;
|
||||||
|
font-size: 17px;
|
||||||
|
text-align: left;
|
||||||
|
text-align: -webkit-left;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 15px;
|
||||||
|
margin: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
margin-top: 25px;
|
||||||
|
font-size: 25px;
|
||||||
|
font-weight: normal;
|
||||||
|
line-height: 22px;
|
||||||
|
color: #333333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
max-width: 680px;
|
||||||
|
margin: 0 auto;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.head-logo {
|
||||||
|
width: 60%;
|
||||||
|
height: auto;
|
||||||
|
display: block;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: #17b53e;
|
||||||
|
}
|
||||||
|
|
||||||
|
a.button {
|
||||||
|
background: #17b53e;
|
||||||
|
font-family: Lato, sans-serif;
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 15px;
|
||||||
|
text-decoration: none;
|
||||||
|
text-align:center;
|
||||||
|
padding: 13px 17px;
|
||||||
|
color: #ffffff;
|
||||||
|
display: table;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
color: #17b53e;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-block {
|
||||||
|
margin-top: 20px;
|
||||||
|
color: #000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
footer {
|
||||||
|
padding: 20px;
|
||||||
|
font-family: Lato, sans-serif;
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 15px;
|
||||||
|
text-align: center;
|
||||||
|
color: #888888;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<header>
|
||||||
|
<div class="head"><img class="head-logo" alt="Welcome Image" loading="lazy" src="http://webapp:3000/img/custom/logo-squared.svg">
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
<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&nonce=123456&inviteCode=welcome&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.
|
||||||
|
</p>
|
||||||
|
<p>PS: If you ignore this e-mail we will not create an account for you. ;)</p>
|
||||||
|
<div class="text-block">
|
||||||
|
<p>See you soon on <a class="organization" href="https://ocelot.social">ocelot.social</a>!</p>
|
||||||
|
<p>– The ocelot.social Team</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<footer>
|
||||||
|
<div class="footer"></div><a href="https://ocelot.social">ocelot.social Community</a>
|
||||||
|
</footer>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>",
|
||||||
|
"subject": "Welcome to ocelot.social",
|
||||||
|
"text": "WELCOME TO OCELOT.SOCIAL!
|
||||||
|
|
||||||
|
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:
|
||||||
|
|
||||||
|
Confirm your e-mail address
|
||||||
|
[http://webapp:3000/registration?email=user%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
|
||||||
|
|
||||||
|
However, this only works if you have registered through our website.
|
||||||
|
|
||||||
|
If you didn't sign up for ocelot.social 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.
|
||||||
|
|
||||||
|
PS: If you ignore this e-mail we will not create an account for you. ;)
|
||||||
|
|
||||||
|
See you soon on ocelot.social [https://ocelot.social]!
|
||||||
|
|
||||||
|
– The ocelot.social Team
|
||||||
|
|
||||||
|
|
||||||
|
ocelot.social Community [https://ocelot.social]",
|
||||||
|
"to": "user@example.org",
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`sendRegistrationMail with invite code German renders correctly 1`] = `
|
||||||
|
{
|
||||||
|
"attachments": [],
|
||||||
|
"from": "ocelot.social",
|
||||||
|
"html": "<!DOCTYPE html>
|
||||||
|
<html lang="de">
|
||||||
|
<head>
|
||||||
|
<meta content="multipart/html; charset=UTF-8" http-equiv="content-type">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<style>.wf-force-outline-none[tabindex="-1"]:focus{outline:none;}</style>
|
||||||
|
<style>body{
|
||||||
|
display: block;
|
||||||
|
font-family: Lato, sans-serif;
|
||||||
|
font-size: 17px;
|
||||||
|
text-align: left;
|
||||||
|
text-align: -webkit-left;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 15px;
|
||||||
|
margin: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
margin-top: 25px;
|
||||||
|
font-size: 25px;
|
||||||
|
font-weight: normal;
|
||||||
|
line-height: 22px;
|
||||||
|
color: #333333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
max-width: 680px;
|
||||||
|
margin: 0 auto;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.head-logo {
|
||||||
|
width: 60%;
|
||||||
|
height: auto;
|
||||||
|
display: block;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: #17b53e;
|
||||||
|
}
|
||||||
|
|
||||||
|
a.button {
|
||||||
|
background: #17b53e;
|
||||||
|
font-family: Lato, sans-serif;
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 15px;
|
||||||
|
text-decoration: none;
|
||||||
|
text-align:center;
|
||||||
|
padding: 13px 17px;
|
||||||
|
color: #ffffff;
|
||||||
|
display: table;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
color: #17b53e;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-block {
|
||||||
|
margin-top: 20px;
|
||||||
|
color: #000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
footer {
|
||||||
|
padding: 20px;
|
||||||
|
font-family: Lato, sans-serif;
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 15px;
|
||||||
|
text-align: center;
|
||||||
|
color: #888888;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<header>
|
||||||
|
<div class="head"><img class="head-logo" alt="Welcome Image" loading="lazy" src="http://webapp:3000/img/custom/logo-squared.svg">
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
<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&nonce=123456&inviteCode=welcome&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.
|
||||||
|
</p>
|
||||||
|
<p>PS: Wenn Du keinen Account bei uns möchtest, kannst Du diese E-Mail einfach ignorieren. ;)</p>
|
||||||
|
<div class="text-block">
|
||||||
|
<p>Bis bald bei <a class="organization" href="https://ocelot.social">ocelot.social</a>!</p>
|
||||||
|
<p>– Dein ocelot.social Team</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<footer>
|
||||||
|
<div class="footer"></div><a href="https://ocelot.social">ocelot.social Community</a>
|
||||||
|
</footer>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>",
|
||||||
|
"subject": "Willkommen bei ocelot.social",
|
||||||
|
"text": "WILLKOMMEN BEI OCELOT.SOCIAL!
|
||||||
|
|
||||||
|
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:
|
||||||
|
|
||||||
|
Bestätige Deine E-Mail Adresse
|
||||||
|
[http://webapp:3000/registration?email=user%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
|
||||||
|
|
||||||
|
Das funktioniert allerdings nur, wenn du Dich über unsere Website registriert
|
||||||
|
hast.
|
||||||
|
|
||||||
|
Falls Du Dich nicht selbst bei ocelot.social angemeldet hast, schau doch mal
|
||||||
|
vorbei! Wir sind ein gemeinnütziges Aktionsnetzwerk – von Menschen für Menschen.
|
||||||
|
|
||||||
|
PS: Wenn Du keinen Account bei uns möchtest, kannst Du diese E-Mail einfach
|
||||||
|
ignorieren. ;)
|
||||||
|
|
||||||
|
Bis bald bei ocelot.social [https://ocelot.social]!
|
||||||
|
|
||||||
|
– Dein ocelot.social Team
|
||||||
|
|
||||||
|
|
||||||
|
ocelot.social Community [https://ocelot.social]",
|
||||||
|
"to": "user@example.org",
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`sendRegistrationMail without invite code English renders correctly 1`] = `
|
||||||
|
{
|
||||||
|
"attachments": [],
|
||||||
|
"from": "ocelot.social",
|
||||||
|
"html": "<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta content="multipart/html; charset=UTF-8" http-equiv="content-type">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<style>.wf-force-outline-none[tabindex="-1"]:focus{outline:none;}</style>
|
||||||
|
<style>body{
|
||||||
|
display: block;
|
||||||
|
font-family: Lato, sans-serif;
|
||||||
|
font-size: 17px;
|
||||||
|
text-align: left;
|
||||||
|
text-align: -webkit-left;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 15px;
|
||||||
|
margin: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
margin-top: 25px;
|
||||||
|
font-size: 25px;
|
||||||
|
font-weight: normal;
|
||||||
|
line-height: 22px;
|
||||||
|
color: #333333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
max-width: 680px;
|
||||||
|
margin: 0 auto;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.head-logo {
|
||||||
|
width: 60%;
|
||||||
|
height: auto;
|
||||||
|
display: block;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: #17b53e;
|
||||||
|
}
|
||||||
|
|
||||||
|
a.button {
|
||||||
|
background: #17b53e;
|
||||||
|
font-family: Lato, sans-serif;
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 15px;
|
||||||
|
text-decoration: none;
|
||||||
|
text-align:center;
|
||||||
|
padding: 13px 17px;
|
||||||
|
color: #ffffff;
|
||||||
|
display: table;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
color: #17b53e;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-block {
|
||||||
|
margin-top: 20px;
|
||||||
|
color: #000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
footer {
|
||||||
|
padding: 20px;
|
||||||
|
font-family: Lato, sans-serif;
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 15px;
|
||||||
|
text-align: center;
|
||||||
|
color: #888888;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<header>
|
||||||
|
<div class="head"><img class="head-logo" alt="Welcome Image" loading="lazy" src="http://webapp:3000/img/custom/logo-squared.svg">
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
<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&nonce=123456&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.
|
||||||
|
</p>
|
||||||
|
<p>PS: If you ignore this e-mail we will not create an account for you. ;)</p>
|
||||||
|
<div class="text-block">
|
||||||
|
<p>See you soon on <a class="organization" href="https://ocelot.social">ocelot.social</a>!</p>
|
||||||
|
<p>– The ocelot.social Team</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<footer>
|
||||||
|
<div class="footer"></div><a href="https://ocelot.social">ocelot.social Community</a>
|
||||||
|
</footer>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>",
|
||||||
|
"subject": "Welcome to ocelot.social",
|
||||||
|
"text": "WELCOME TO OCELOT.SOCIAL!
|
||||||
|
|
||||||
|
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:
|
||||||
|
|
||||||
|
Confirm your e-mail address
|
||||||
|
[http://webapp:3000/registration?email=user%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
|
||||||
|
|
||||||
|
However, this only works if you have registered through our website.
|
||||||
|
|
||||||
|
If you didn't sign up for ocelot.social 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.
|
||||||
|
|
||||||
|
PS: If you ignore this e-mail we will not create an account for you. ;)
|
||||||
|
|
||||||
|
See you soon on ocelot.social [https://ocelot.social]!
|
||||||
|
|
||||||
|
– The ocelot.social Team
|
||||||
|
|
||||||
|
|
||||||
|
ocelot.social Community [https://ocelot.social]",
|
||||||
|
"to": "user@example.org",
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`sendRegistrationMail without invite code German renders correctly 1`] = `
|
||||||
|
{
|
||||||
|
"attachments": [],
|
||||||
|
"from": "ocelot.social",
|
||||||
|
"html": "<!DOCTYPE html>
|
||||||
|
<html lang="de">
|
||||||
|
<head>
|
||||||
|
<meta content="multipart/html; charset=UTF-8" http-equiv="content-type">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<style>.wf-force-outline-none[tabindex="-1"]:focus{outline:none;}</style>
|
||||||
|
<style>body{
|
||||||
|
display: block;
|
||||||
|
font-family: Lato, sans-serif;
|
||||||
|
font-size: 17px;
|
||||||
|
text-align: left;
|
||||||
|
text-align: -webkit-left;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 15px;
|
||||||
|
margin: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
margin-top: 25px;
|
||||||
|
font-size: 25px;
|
||||||
|
font-weight: normal;
|
||||||
|
line-height: 22px;
|
||||||
|
color: #333333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
max-width: 680px;
|
||||||
|
margin: 0 auto;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.head-logo {
|
||||||
|
width: 60%;
|
||||||
|
height: auto;
|
||||||
|
display: block;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: #17b53e;
|
||||||
|
}
|
||||||
|
|
||||||
|
a.button {
|
||||||
|
background: #17b53e;
|
||||||
|
font-family: Lato, sans-serif;
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 15px;
|
||||||
|
text-decoration: none;
|
||||||
|
text-align:center;
|
||||||
|
padding: 13px 17px;
|
||||||
|
color: #ffffff;
|
||||||
|
display: table;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
color: #17b53e;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-block {
|
||||||
|
margin-top: 20px;
|
||||||
|
color: #000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
footer {
|
||||||
|
padding: 20px;
|
||||||
|
font-family: Lato, sans-serif;
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 15px;
|
||||||
|
text-align: center;
|
||||||
|
color: #888888;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<header>
|
||||||
|
<div class="head"><img class="head-logo" alt="Welcome Image" loading="lazy" src="http://webapp:3000/img/custom/logo-squared.svg">
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
<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&nonce=123456&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.
|
||||||
|
</p>
|
||||||
|
<p>PS: Wenn Du keinen Account bei uns möchtest, kannst Du diese E-Mail einfach ignorieren. ;)</p>
|
||||||
|
<div class="text-block">
|
||||||
|
<p>Bis bald bei <a class="organization" href="https://ocelot.social">ocelot.social</a>!</p>
|
||||||
|
<p>– Dein ocelot.social Team</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<footer>
|
||||||
|
<div class="footer"></div><a href="https://ocelot.social">ocelot.social Community</a>
|
||||||
|
</footer>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>",
|
||||||
|
"subject": "Willkommen bei ocelot.social",
|
||||||
|
"text": "WILLKOMMEN BEI OCELOT.SOCIAL!
|
||||||
|
|
||||||
|
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:
|
||||||
|
|
||||||
|
Bestätige Deine E-Mail Adresse
|
||||||
|
[http://webapp:3000/registration?email=user%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
|
||||||
|
|
||||||
|
Das funktioniert allerdings nur, wenn du Dich über unsere Website registriert
|
||||||
|
hast.
|
||||||
|
|
||||||
|
Falls Du Dich nicht selbst bei ocelot.social angemeldet hast, schau doch mal
|
||||||
|
vorbei! Wir sind ein gemeinnütziges Aktionsnetzwerk – von Menschen für Menschen.
|
||||||
|
|
||||||
|
PS: Wenn Du keinen Account bei uns möchtest, kannst Du diese E-Mail einfach
|
||||||
|
ignorieren. ;)
|
||||||
|
|
||||||
|
Bis bald bei ocelot.social [https://ocelot.social]!
|
||||||
|
|
||||||
|
– Dein ocelot.social Team
|
||||||
|
|
||||||
|
|
||||||
|
ocelot.social Community [https://ocelot.social]",
|
||||||
|
"to": "user@example.org",
|
||||||
|
}
|
||||||
|
`;
|
||||||
@ -0,0 +1,260 @@
|
|||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`sendResetPasswordMail English renders correctly 1`] = `
|
||||||
|
{
|
||||||
|
"attachments": [],
|
||||||
|
"from": "ocelot.social",
|
||||||
|
"html": "<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta content="multipart/html; charset=UTF-8" http-equiv="content-type">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<style>.wf-force-outline-none[tabindex="-1"]:focus{outline:none;}</style>
|
||||||
|
<style>body{
|
||||||
|
display: block;
|
||||||
|
font-family: Lato, sans-serif;
|
||||||
|
font-size: 17px;
|
||||||
|
text-align: left;
|
||||||
|
text-align: -webkit-left;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 15px;
|
||||||
|
margin: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
margin-top: 25px;
|
||||||
|
font-size: 25px;
|
||||||
|
font-weight: normal;
|
||||||
|
line-height: 22px;
|
||||||
|
color: #333333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
max-width: 680px;
|
||||||
|
margin: 0 auto;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.head-logo {
|
||||||
|
width: 60%;
|
||||||
|
height: auto;
|
||||||
|
display: block;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: #17b53e;
|
||||||
|
}
|
||||||
|
|
||||||
|
a.button {
|
||||||
|
background: #17b53e;
|
||||||
|
font-family: Lato, sans-serif;
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 15px;
|
||||||
|
text-decoration: none;
|
||||||
|
text-align:center;
|
||||||
|
padding: 13px 17px;
|
||||||
|
color: #ffffff;
|
||||||
|
display: table;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
color: #17b53e;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-block {
|
||||||
|
margin-top: 20px;
|
||||||
|
color: #000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
footer {
|
||||||
|
padding: 20px;
|
||||||
|
font-family: Lato, sans-serif;
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 15px;
|
||||||
|
text-align: center;
|
||||||
|
color: #888888;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<header>
|
||||||
|
<div class="head"><img class="head-logo" alt="Welcome Image" loading="lazy" src="http://webapp:3000/img/custom/logo-squared.svg">
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
<h2>Hello Jenny Rostock,</h2>
|
||||||
|
<div class="wrapper">
|
||||||
|
<div class="content"></div>
|
||||||
|
<p>So, you forgot your password? No problem! Just click the button below to reset it within the next 24 hours:</p><a class="button" href="http://webapp:3000/password-reset/change-password?email=user%40example.org&nonce=123456">Confirm your e-mail address</a>
|
||||||
|
<p>If you didn't request a new password feel free to ignore this e-mail.</p>
|
||||||
|
<p>If the above button doesn't work you can also copy the following code into your browser window: <span>123456</span></p>
|
||||||
|
<div class="text-block">
|
||||||
|
<p>See you soon on <a class="organization" href="https://ocelot.social">ocelot.social</a>!</p>
|
||||||
|
<p>– The ocelot.social Team</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<footer>
|
||||||
|
<div class="footer"></div><a href="https://ocelot.social">ocelot.social Community</a>
|
||||||
|
</footer>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>",
|
||||||
|
"subject": "Reset Password ocelot.social",
|
||||||
|
"text": "HELLO JENNY ROSTOCK,
|
||||||
|
|
||||||
|
So, you forgot your password? No problem! Just click the button below to reset
|
||||||
|
it within the next 24 hours:
|
||||||
|
|
||||||
|
Confirm your e-mail address
|
||||||
|
[http://webapp:3000/password-reset/change-password?email=user%40example.org&nonce=123456]
|
||||||
|
|
||||||
|
If you didn't request a new password feel free to ignore this e-mail.
|
||||||
|
|
||||||
|
If the above button doesn't work you can also copy the following code into your
|
||||||
|
browser window: 123456
|
||||||
|
|
||||||
|
See you soon on ocelot.social [https://ocelot.social]!
|
||||||
|
|
||||||
|
– The ocelot.social Team
|
||||||
|
|
||||||
|
|
||||||
|
ocelot.social Community [https://ocelot.social]",
|
||||||
|
"to": "user@example.org",
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`sendResetPasswordMail German renders correctly 1`] = `
|
||||||
|
{
|
||||||
|
"attachments": [],
|
||||||
|
"from": "ocelot.social",
|
||||||
|
"html": "<!DOCTYPE html>
|
||||||
|
<html lang="de">
|
||||||
|
<head>
|
||||||
|
<meta content="multipart/html; charset=UTF-8" http-equiv="content-type">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<style>.wf-force-outline-none[tabindex="-1"]:focus{outline:none;}</style>
|
||||||
|
<style>body{
|
||||||
|
display: block;
|
||||||
|
font-family: Lato, sans-serif;
|
||||||
|
font-size: 17px;
|
||||||
|
text-align: left;
|
||||||
|
text-align: -webkit-left;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 15px;
|
||||||
|
margin: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
margin-top: 25px;
|
||||||
|
font-size: 25px;
|
||||||
|
font-weight: normal;
|
||||||
|
line-height: 22px;
|
||||||
|
color: #333333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
max-width: 680px;
|
||||||
|
margin: 0 auto;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.head-logo {
|
||||||
|
width: 60%;
|
||||||
|
height: auto;
|
||||||
|
display: block;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: #17b53e;
|
||||||
|
}
|
||||||
|
|
||||||
|
a.button {
|
||||||
|
background: #17b53e;
|
||||||
|
font-family: Lato, sans-serif;
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 15px;
|
||||||
|
text-decoration: none;
|
||||||
|
text-align:center;
|
||||||
|
padding: 13px 17px;
|
||||||
|
color: #ffffff;
|
||||||
|
display: table;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
color: #17b53e;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-block {
|
||||||
|
margin-top: 20px;
|
||||||
|
color: #000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
footer {
|
||||||
|
padding: 20px;
|
||||||
|
font-family: Lato, sans-serif;
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 15px;
|
||||||
|
text-align: center;
|
||||||
|
color: #888888;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<header>
|
||||||
|
<div class="head"><img class="head-logo" alt="Welcome Image" loading="lazy" src="http://webapp:3000/img/custom/logo-squared.svg">
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
<h2>Hallo Jenny Rostock,</h2>
|
||||||
|
<div class="wrapper">
|
||||||
|
<div class="content"></div>
|
||||||
|
<p>Du hast also dein Passwort vergessen? Kein Problem! Mit Klick auf diesen Button kannst du innerhalb der nächsten 24 Stunden dein Passwort zurücksetzen:</p><a class="button" href="http://webapp:3000/password-reset/change-password?email=user%40example.org&nonce=123456">Bestätige Deine E-Mail Adresse</a>
|
||||||
|
<p>Falls du kein neues Passwort angefordert hast, kannst du diese E-Mail einfach ignorieren.</p>
|
||||||
|
<p>Sollte der Button für dich nicht funktionieren, kannst du auch folgenden Code in Dein Browserfenster kopieren: <span>123456</span></p>
|
||||||
|
<div class="text-block">
|
||||||
|
<p>Bis bald bei <a class="organization" href="https://ocelot.social">ocelot.social</a>!</p>
|
||||||
|
<p>– Dein ocelot.social Team</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<footer>
|
||||||
|
<div class="footer"></div><a href="https://ocelot.social">ocelot.social Community</a>
|
||||||
|
</footer>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>",
|
||||||
|
"subject": "Neues Passwort ocelot.social",
|
||||||
|
"text": "HALLO JENNY ROSTOCK,
|
||||||
|
|
||||||
|
Du hast also dein Passwort vergessen? Kein Problem! Mit Klick auf diesen Button
|
||||||
|
kannst du innerhalb der nächsten 24 Stunden dein Passwort zurücksetzen:
|
||||||
|
|
||||||
|
Bestätige Deine E-Mail Adresse
|
||||||
|
[http://webapp:3000/password-reset/change-password?email=user%40example.org&nonce=123456]
|
||||||
|
|
||||||
|
Falls du kein neues Passwort angefordert hast, kannst du diese E-Mail einfach
|
||||||
|
ignorieren.
|
||||||
|
|
||||||
|
Sollte der Button für dich nicht funktionieren, kannst du auch folgenden Code in
|
||||||
|
Dein Browserfenster kopieren: 123456
|
||||||
|
|
||||||
|
Bis bald bei ocelot.social [https://ocelot.social]!
|
||||||
|
|
||||||
|
– Dein ocelot.social Team
|
||||||
|
|
||||||
|
|
||||||
|
ocelot.social Community [https://ocelot.social]",
|
||||||
|
"to": "user@example.org",
|
||||||
|
}
|
||||||
|
`;
|
||||||
255
backend/src/emails/__snapshots__/sendWrongEmail.spec.ts.snap
Normal file
255
backend/src/emails/__snapshots__/sendWrongEmail.spec.ts.snap
Normal file
@ -0,0 +1,255 @@
|
|||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`sendWrongEmail English renders correctly 1`] = `
|
||||||
|
{
|
||||||
|
"attachments": [],
|
||||||
|
"from": "ocelot.social",
|
||||||
|
"html": "<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta content="multipart/html; charset=UTF-8" http-equiv="content-type">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<style>.wf-force-outline-none[tabindex="-1"]:focus{outline:none;}</style>
|
||||||
|
<style>body{
|
||||||
|
display: block;
|
||||||
|
font-family: Lato, sans-serif;
|
||||||
|
font-size: 17px;
|
||||||
|
text-align: left;
|
||||||
|
text-align: -webkit-left;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 15px;
|
||||||
|
margin: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
margin-top: 25px;
|
||||||
|
font-size: 25px;
|
||||||
|
font-weight: normal;
|
||||||
|
line-height: 22px;
|
||||||
|
color: #333333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
max-width: 680px;
|
||||||
|
margin: 0 auto;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.head-logo {
|
||||||
|
width: 60%;
|
||||||
|
height: auto;
|
||||||
|
display: block;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: #17b53e;
|
||||||
|
}
|
||||||
|
|
||||||
|
a.button {
|
||||||
|
background: #17b53e;
|
||||||
|
font-family: Lato, sans-serif;
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 15px;
|
||||||
|
text-decoration: none;
|
||||||
|
text-align:center;
|
||||||
|
padding: 13px 17px;
|
||||||
|
color: #ffffff;
|
||||||
|
display: table;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
color: #17b53e;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-block {
|
||||||
|
margin-top: 20px;
|
||||||
|
color: #000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
footer {
|
||||||
|
padding: 20px;
|
||||||
|
font-family: Lato, sans-serif;
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 15px;
|
||||||
|
text-align: center;
|
||||||
|
color: #888888;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<header>
|
||||||
|
<div class="head"><img class="head-logo" alt="Welcome Image" loading="lazy" src="http://webapp:3000/img/custom/logo-squared.svg">
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
<h2>Welcome to ocelot.social!</h2>
|
||||||
|
<div class="wrapper">
|
||||||
|
<div class="content"></div>
|
||||||
|
<p>You requested a password reset but unfortunately we couldn't find an account associated with your e-mail address. Did you maybe use another one when you signed up?</p><a class="button" href="http://webapp:3000/password-reset/request">Try a different e-mail</a>
|
||||||
|
<p>If you don't have an account at <a>ocelot.social</a> yet or if you didn't want to reset your password, please ignore this e-mail.
|
||||||
|
</p>
|
||||||
|
<div class="text-block">
|
||||||
|
<p>See you soon on <a class="organization" href="https://ocelot.social">ocelot.social</a>!</p>
|
||||||
|
<p>– The ocelot.social Team</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<footer>
|
||||||
|
<div class="footer"></div><a href="https://ocelot.social">ocelot.social Community</a>
|
||||||
|
</footer>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>",
|
||||||
|
"subject": "Wrong E-mail? ocelot.social",
|
||||||
|
"text": "WELCOME TO OCELOT.SOCIAL!
|
||||||
|
|
||||||
|
You requested a password reset but unfortunately we couldn't find an account
|
||||||
|
associated with your e-mail address. Did you maybe use another one when you
|
||||||
|
signed up?
|
||||||
|
|
||||||
|
Try a different e-mail [http://webapp:3000/password-reset/request]
|
||||||
|
|
||||||
|
If you don't have an account at ocelot.social yet or if you didn't want to reset
|
||||||
|
your password, please ignore this e-mail.
|
||||||
|
|
||||||
|
See you soon on ocelot.social [https://ocelot.social]!
|
||||||
|
|
||||||
|
– The ocelot.social Team
|
||||||
|
|
||||||
|
|
||||||
|
ocelot.social Community [https://ocelot.social]",
|
||||||
|
"to": "user@example.org",
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`sendWrongEmail German renders correctly 1`] = `
|
||||||
|
{
|
||||||
|
"attachments": [],
|
||||||
|
"from": "ocelot.social",
|
||||||
|
"html": "<!DOCTYPE html>
|
||||||
|
<html lang="de">
|
||||||
|
<head>
|
||||||
|
<meta content="multipart/html; charset=UTF-8" http-equiv="content-type">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<style>.wf-force-outline-none[tabindex="-1"]:focus{outline:none;}</style>
|
||||||
|
<style>body{
|
||||||
|
display: block;
|
||||||
|
font-family: Lato, sans-serif;
|
||||||
|
font-size: 17px;
|
||||||
|
text-align: left;
|
||||||
|
text-align: -webkit-left;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 15px;
|
||||||
|
margin: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
margin-top: 25px;
|
||||||
|
font-size: 25px;
|
||||||
|
font-weight: normal;
|
||||||
|
line-height: 22px;
|
||||||
|
color: #333333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
max-width: 680px;
|
||||||
|
margin: 0 auto;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.head-logo {
|
||||||
|
width: 60%;
|
||||||
|
height: auto;
|
||||||
|
display: block;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: #17b53e;
|
||||||
|
}
|
||||||
|
|
||||||
|
a.button {
|
||||||
|
background: #17b53e;
|
||||||
|
font-family: Lato, sans-serif;
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 15px;
|
||||||
|
text-decoration: none;
|
||||||
|
text-align:center;
|
||||||
|
padding: 13px 17px;
|
||||||
|
color: #ffffff;
|
||||||
|
display: table;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
color: #17b53e;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-block {
|
||||||
|
margin-top: 20px;
|
||||||
|
color: #000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
footer {
|
||||||
|
padding: 20px;
|
||||||
|
font-family: Lato, sans-serif;
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 15px;
|
||||||
|
text-align: center;
|
||||||
|
color: #888888;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<header>
|
||||||
|
<div class="head"><img class="head-logo" alt="Welcome Image" loading="lazy" src="http://webapp:3000/img/custom/logo-squared.svg">
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
<h2>Willkommen bei ocelot.social!</h2>
|
||||||
|
<div class="wrapper">
|
||||||
|
<div class="content"></div>
|
||||||
|
<p>Du hast bei uns ein neues Passwort angefordert – leider haben wir aber keinen Account mit deiner E-Mailadresse gefunden. Kann es sein, dass du mit einer anderen Adresse bei uns angemeldet bist?</p><a class="button" href="http://webapp:3000/password-reset/request">Versuch' es mit einer anderen E-Mail</a>
|
||||||
|
<p>Wenn du noch keinen Account bei <a>ocelot.social</a> hast oder dein Password gar nicht ändern willst, kannst du diese E-Mail einfach ignorieren!
|
||||||
|
</p>
|
||||||
|
<div class="text-block">
|
||||||
|
<p>Bis bald bei <a class="organization" href="https://ocelot.social">ocelot.social</a>!</p>
|
||||||
|
<p>– Dein ocelot.social Team</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<footer>
|
||||||
|
<div class="footer"></div><a href="https://ocelot.social">ocelot.social Community</a>
|
||||||
|
</footer>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>",
|
||||||
|
"subject": "Falsche Mailaddresse? ocelot.social",
|
||||||
|
"text": "WILLKOMMEN BEI OCELOT.SOCIAL!
|
||||||
|
|
||||||
|
Du hast bei uns ein neues Passwort angefordert – leider haben wir aber keinen
|
||||||
|
Account mit deiner E-Mailadresse gefunden. Kann es sein, dass du mit einer
|
||||||
|
anderen Adresse bei uns angemeldet bist?
|
||||||
|
|
||||||
|
Versuch' es mit einer anderen E-Mail [http://webapp:3000/password-reset/request]
|
||||||
|
|
||||||
|
Wenn du noch keinen Account bei ocelot.social hast oder dein Password gar nicht
|
||||||
|
ändern willst, kannst du diese E-Mail einfach ignorieren!
|
||||||
|
|
||||||
|
Bis bald bei ocelot.social [https://ocelot.social]!
|
||||||
|
|
||||||
|
– Dein ocelot.social Team
|
||||||
|
|
||||||
|
|
||||||
|
ocelot.social Community [https://ocelot.social]",
|
||||||
|
"to": "user@example.org",
|
||||||
|
}
|
||||||
|
`;
|
||||||
@ -7,12 +7,32 @@
|
|||||||
"followedUserPosted": "Neuer Beitrag von gefolgtem Nutzer",
|
"followedUserPosted": "Neuer Beitrag von gefolgtem Nutzer",
|
||||||
"mentionedInComment": "Erwähnung in Kommentar",
|
"mentionedInComment": "Erwähnung in Kommentar",
|
||||||
"mentionedInPost": "Erwähnung in Beitrag",
|
"mentionedInPost": "Erwähnung in Beitrag",
|
||||||
|
"newEmail": "Neue E-Mail Addresse",
|
||||||
"removedUserFromGroup": "Aus Gruppe entfernt",
|
"removedUserFromGroup": "Aus Gruppe entfernt",
|
||||||
"postInGroup": "Neuer Beitrag in Gruppe",
|
"postInGroup": "Neuer Beitrag in Gruppe",
|
||||||
|
"resetPassword": "Neues Passwort",
|
||||||
"userJoinedGroup": "Nutzer tritt Gruppe bei",
|
"userJoinedGroup": "Nutzer tritt Gruppe bei",
|
||||||
"userLeftGroup": "Nutzer verlässt Gruppe"
|
"userLeftGroup": "Nutzer verlässt Gruppe",
|
||||||
|
"wrongEmail": "Falsche Mailaddresse?"
|
||||||
|
},
|
||||||
|
"registration": {
|
||||||
|
"introduction": "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:",
|
||||||
|
"codeHint": "Sollte der Button für Dich nicht funktionieren, kannst Du auch folgenden Code in Dein Browserfenster kopieren: ",
|
||||||
|
"codeHintException": "Das funktioniert allerdings nur, wenn du Dich über unsere Website registriert hast.",
|
||||||
|
"notYouStart": "Falls Du Dich nicht selbst bei ",
|
||||||
|
"notYouEnd": " angemeldet hast, schau doch mal vorbei! Wir sind ein gemeinnütziges Aktionsnetzwerk – von Menschen für Menschen.",
|
||||||
|
"ps": "PS: Wenn Du keinen Account bei uns möchtest, kannst Du diese E-Mail einfach ignorieren. ;)"
|
||||||
|
},
|
||||||
|
"emailVerification": {
|
||||||
|
"codeHint": "Sollte der Button für Dich nicht funktionieren, kannst Du auch folgenden Code in Dein Browserfenster kopieren: ",
|
||||||
|
"introduction": "Du möchtest also deine E-Mail ändern? Kein Problem! Mit Klick auf diesen Button kannst Du Deine neue E-Mail Adresse bestätigen:",
|
||||||
|
"doNotChange": "Falls Du deine E-Mail Adresse doch nicht ändern möchtest, kannst du diese Nachricht einfach ignorieren. "
|
||||||
},
|
},
|
||||||
"buttons": {
|
"buttons": {
|
||||||
|
"confirmEmail": "Bestätige Deine E-Mail Adresse",
|
||||||
|
"resetPassword": "Passwort zurücksetzen",
|
||||||
|
"tryAgain": "Versuch' es mit einer anderen E-Mail",
|
||||||
|
"verifyEmail": "E-Mail Adresse bestätigen",
|
||||||
"viewChat": "Chat anzeigen",
|
"viewChat": "Chat anzeigen",
|
||||||
"viewComment": "Kommentar ansehen",
|
"viewComment": "Kommentar ansehen",
|
||||||
"viewGroup": "Gruppe ansehen",
|
"viewGroup": "Gruppe ansehen",
|
||||||
@ -23,7 +43,19 @@
|
|||||||
"seeYou": "Bis bald bei ",
|
"seeYou": "Bis bald bei ",
|
||||||
"yourTeam": "– Dein {team} Team",
|
"yourTeam": "– Dein {team} Team",
|
||||||
"settingsHint": "PS: Möchtest du keine E-Mails mehr erhalten, dann ändere deine ",
|
"settingsHint": "PS: Möchtest du keine E-Mails mehr erhalten, dann ändere deine ",
|
||||||
"settingsName": "Benachrichtigungseinstellungen"
|
"settingsName": "Benachrichtigungseinstellungen",
|
||||||
|
"welcome": "Willkommen bei"
|
||||||
|
},
|
||||||
|
"resetPassword": {
|
||||||
|
"codeHint": "Sollte der Button für dich nicht funktionieren, kannst du auch folgenden Code in Dein Browserfenster kopieren: ",
|
||||||
|
"ignore": "Falls du kein neues Passwort angefordert hast, kannst du diese E-Mail einfach ignorieren.",
|
||||||
|
"introduction": "Du hast also dein Passwort vergessen? Kein Problem! Mit Klick auf diesen Button kannst du innerhalb der nächsten 24 Stunden dein Passwort zurücksetzen:"
|
||||||
|
},
|
||||||
|
"wrongEmail": {
|
||||||
|
"codeHint": "Sollte der Button für Dich nicht funktionieren, kannst Du auch folgenden Code in Dein Browserfenster kopieren: ",
|
||||||
|
"ignoreEnd": " hast oder dein Password gar nicht ändern willst, kannst du diese E-Mail einfach ignorieren!",
|
||||||
|
"ignoreStart": "Wenn du noch keinen Account bei ",
|
||||||
|
"introduction": "Du hast bei uns ein neues Passwort angefordert – leider haben wir aber keinen Account mit deiner E-Mailadresse gefunden. Kann es sein, dass du mit einer anderen Adresse bei uns angemeldet bist?"
|
||||||
},
|
},
|
||||||
"changedGroupMemberRole": "deine Rolle in der Gruppe „{groupName}“ wurde geändert. Klicke auf den Knopf, um diese Gruppe zu sehen:",
|
"changedGroupMemberRole": "deine Rolle in der Gruppe „{groupName}“ wurde geändert. Klicke auf den Knopf, um diese Gruppe zu sehen:",
|
||||||
"chatMessageStart": "du hast eine neue Chat-Nachricht von ",
|
"chatMessageStart": "du hast eine neue Chat-Nachricht von ",
|
||||||
|
|||||||
@ -7,12 +7,32 @@
|
|||||||
"followedUserPosted": "New post by followd user",
|
"followedUserPosted": "New post by followd user",
|
||||||
"mentionedInComment": "Mentioned in comment",
|
"mentionedInComment": "Mentioned in comment",
|
||||||
"mentionedInPost": "Mentioned in post",
|
"mentionedInPost": "Mentioned in post",
|
||||||
|
"newEmail": "New E-Mail Address",
|
||||||
"removedUserFromGroup": "Removed from group",
|
"removedUserFromGroup": "Removed from group",
|
||||||
"postInGroup": "New post in group",
|
"postInGroup": "New post in group",
|
||||||
|
"resetPassword": "Reset Password",
|
||||||
"userJoinedGroup": "User joined group",
|
"userJoinedGroup": "User joined group",
|
||||||
"userLeftGroup": "User left group"
|
"userLeftGroup": "User left group",
|
||||||
|
"wrongEmail": "Wrong E-mail?"
|
||||||
|
},
|
||||||
|
"registration": {
|
||||||
|
"introduction": "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:",
|
||||||
|
"codeHint": "If the above button doesn't work, you can also copy the following code into your browser window: ",
|
||||||
|
"codeHintException": "However, this only works if you have registered through our website.",
|
||||||
|
"notYouStart": "If you didn't sign up for ",
|
||||||
|
"notYouEnd": " 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.",
|
||||||
|
"ps": "PS: If you ignore this e-mail we will not create an account for you. ;)"
|
||||||
|
},
|
||||||
|
"emailVerification": {
|
||||||
|
"codeHint": "If the above button doesn't work, you can also copy the following code into your browser window: ",
|
||||||
|
"introduction": "So, you want to change your e-mail? No problem! Just click the button below to verify your new address:",
|
||||||
|
"doNotChange": "If you don't want to change your e-mail address feel free to ignore this message. "
|
||||||
},
|
},
|
||||||
"buttons": {
|
"buttons": {
|
||||||
|
"confirmEmail": "Confirm your e-mail address",
|
||||||
|
"resetPassword": "Reset password",
|
||||||
|
"tryAgain": "Try a different e-mail",
|
||||||
|
"verifyEmail": "Verify e-mail address",
|
||||||
"viewChat": "Show Chat",
|
"viewChat": "Show Chat",
|
||||||
"viewComment": "View comment",
|
"viewComment": "View comment",
|
||||||
"viewGroup": "View group",
|
"viewGroup": "View group",
|
||||||
@ -23,7 +43,18 @@
|
|||||||
"seeYou": "See you soon on ",
|
"seeYou": "See you soon on ",
|
||||||
"yourTeam": "– The {team} Team",
|
"yourTeam": "– The {team} Team",
|
||||||
"settingsHint": "PS: If you don't want to receive e-mails anymore, change your ",
|
"settingsHint": "PS: If you don't want to receive e-mails anymore, change your ",
|
||||||
"settingsName": "notification settings"
|
"settingsName": "notification settings",
|
||||||
|
"welcome": "Welcome to"
|
||||||
|
},
|
||||||
|
"resetPassword": {
|
||||||
|
"codeHint": "If the above button doesn't work you can also copy the following code into your browser window: ",
|
||||||
|
"ignore": "If you didn't request a new password feel free to ignore this e-mail.",
|
||||||
|
"introduction": "So, you forgot your password? No problem! Just click the button below to reset it within the next 24 hours:"
|
||||||
|
},
|
||||||
|
"wrongEmail": {
|
||||||
|
"ignoreEnd": " yet or if you didn't want to reset your password, please ignore this e-mail.",
|
||||||
|
"ignoreStart": "If you don't have an account at ",
|
||||||
|
"introduction": "You requested a password reset but unfortunately we couldn't find an account associated with your e-mail address. Did you maybe use another one when you signed up?"
|
||||||
},
|
},
|
||||||
"changedGroupMemberRole": "your role in the group “{groupName}” has been changed. Click on the button to view this group:",
|
"changedGroupMemberRole": "your role in the group “{groupName}” has been changed. Click on the button to view this group:",
|
||||||
"chatMessageStart": "you have received a new chat message from ",
|
"chatMessageStart": "you have received a new chat message from ",
|
||||||
|
|||||||
@ -28,6 +28,7 @@ const defaultParams = {
|
|||||||
ORGANIZATION_URL: CONFIG.ORGANIZATION_URL,
|
ORGANIZATION_URL: CONFIG.ORGANIZATION_URL,
|
||||||
supportUrl: CONFIG.SUPPORT_URL,
|
supportUrl: CONFIG.SUPPORT_URL,
|
||||||
settingsUrl,
|
settingsUrl,
|
||||||
|
renderSettingsUrl: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
export const transport = createTransport({
|
export const transport = createTransport({
|
||||||
@ -202,3 +203,137 @@ export const sendChatMessageMail = async (
|
|||||||
throw new Error(error)
|
throw new Error(error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface VerifyMailInput {
|
||||||
|
email: string
|
||||||
|
nonce: string
|
||||||
|
locale: string
|
||||||
|
}
|
||||||
|
|
||||||
|
interface RegistrationMailInput extends VerifyMailInput {
|
||||||
|
inviteCode?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export const sendRegistrationMail = async (
|
||||||
|
data: RegistrationMailInput,
|
||||||
|
): Promise<OriginalMessage> => {
|
||||||
|
const { nonce, locale, inviteCode } = data
|
||||||
|
const to = data.email
|
||||||
|
const actionUrl = new URL('/registration', CONFIG.CLIENT_URI)
|
||||||
|
actionUrl.searchParams.set('email', to)
|
||||||
|
actionUrl.searchParams.set('nonce', nonce)
|
||||||
|
if (inviteCode) {
|
||||||
|
actionUrl.searchParams.set('inviteCode', inviteCode)
|
||||||
|
actionUrl.searchParams.set('method', 'invite-code')
|
||||||
|
} else {
|
||||||
|
actionUrl.searchParams.set('method', 'invite-mail')
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const { originalMessage } = await email.send({
|
||||||
|
template: path.join(__dirname, 'templates', 'registration'),
|
||||||
|
message: {
|
||||||
|
to,
|
||||||
|
},
|
||||||
|
locals: {
|
||||||
|
...defaultParams,
|
||||||
|
locale,
|
||||||
|
actionUrl,
|
||||||
|
nonce,
|
||||||
|
renderSettingsUrl: false,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
return originalMessage as OriginalMessage
|
||||||
|
} catch (error) {
|
||||||
|
throw new Error(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
interface EmailVerificationInput extends VerifyMailInput {
|
||||||
|
name: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export const sendEmailVerification = async (
|
||||||
|
data: EmailVerificationInput,
|
||||||
|
): Promise<OriginalMessage> => {
|
||||||
|
const { nonce, locale, name } = data
|
||||||
|
const to = data.email
|
||||||
|
const actionUrl = new URL('/settings/my-email-address/verify', CONFIG.CLIENT_URI)
|
||||||
|
actionUrl.searchParams.set('email', to)
|
||||||
|
actionUrl.searchParams.set('nonce', nonce)
|
||||||
|
|
||||||
|
try {
|
||||||
|
const { originalMessage } = await email.send({
|
||||||
|
template: path.join(__dirname, 'templates', 'emailVerification'),
|
||||||
|
message: {
|
||||||
|
to,
|
||||||
|
},
|
||||||
|
locals: {
|
||||||
|
...defaultParams,
|
||||||
|
locale,
|
||||||
|
actionUrl,
|
||||||
|
nonce,
|
||||||
|
name,
|
||||||
|
renderSettingsUrl: false,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
return originalMessage as OriginalMessage
|
||||||
|
} catch (error) {
|
||||||
|
throw new Error(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const sendResetPasswordMail = async (
|
||||||
|
data: EmailVerificationInput,
|
||||||
|
): Promise<OriginalMessage> => {
|
||||||
|
const { nonce, locale, name } = data
|
||||||
|
const to = data.email
|
||||||
|
const actionUrl = new URL('/password-reset/change-password', CONFIG.CLIENT_URI)
|
||||||
|
actionUrl.searchParams.set('email', to)
|
||||||
|
actionUrl.searchParams.set('nonce', nonce)
|
||||||
|
try {
|
||||||
|
const { originalMessage } = await email.send({
|
||||||
|
template: path.join(__dirname, 'templates', 'resetPassword'),
|
||||||
|
message: {
|
||||||
|
to,
|
||||||
|
},
|
||||||
|
locals: {
|
||||||
|
...defaultParams,
|
||||||
|
locale,
|
||||||
|
actionUrl,
|
||||||
|
nonce,
|
||||||
|
name,
|
||||||
|
renderSettingsUrl: false,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
return originalMessage as OriginalMessage
|
||||||
|
} catch (error) {
|
||||||
|
throw new Error(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const sendWrongEmail = async (data: {
|
||||||
|
locale: string
|
||||||
|
email: string
|
||||||
|
}): Promise<OriginalMessage> => {
|
||||||
|
const { locale } = data
|
||||||
|
const to = data.email
|
||||||
|
const actionUrl = new URL('/password-reset/request', CONFIG.CLIENT_URI)
|
||||||
|
try {
|
||||||
|
const { originalMessage } = await email.send({
|
||||||
|
template: path.join(__dirname, 'templates', 'wrongEmail'),
|
||||||
|
message: {
|
||||||
|
to,
|
||||||
|
},
|
||||||
|
locals: {
|
||||||
|
...defaultParams,
|
||||||
|
locale,
|
||||||
|
actionUrl,
|
||||||
|
renderSettingsUrl: false,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
return originalMessage as OriginalMessage
|
||||||
|
} catch (error) {
|
||||||
|
throw new Error(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
35
backend/src/emails/sendEmailVerification.spec.ts
Normal file
35
backend/src/emails/sendEmailVerification.spec.ts
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
import { sendEmailVerification } from './sendEmail'
|
||||||
|
|
||||||
|
describe('sendEmailVerification', () => {
|
||||||
|
const data: {
|
||||||
|
email: string
|
||||||
|
nonce: string
|
||||||
|
locale: string
|
||||||
|
name: string
|
||||||
|
} = {
|
||||||
|
email: 'user@example.org',
|
||||||
|
nonce: '123456',
|
||||||
|
locale: 'en',
|
||||||
|
name: 'User',
|
||||||
|
}
|
||||||
|
|
||||||
|
describe('English', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
data.locale = 'en'
|
||||||
|
})
|
||||||
|
|
||||||
|
it('renders correctly', async () => {
|
||||||
|
await expect(sendEmailVerification(data)).resolves.toMatchSnapshot()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('German', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
data.locale = 'de'
|
||||||
|
})
|
||||||
|
|
||||||
|
it('renders correctly', async () => {
|
||||||
|
await expect(sendEmailVerification(data)).resolves.toMatchSnapshot()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
63
backend/src/emails/sendRegistrationMail.spec.ts
Normal file
63
backend/src/emails/sendRegistrationMail.spec.ts
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
import { sendRegistrationMail } from './sendEmail'
|
||||||
|
|
||||||
|
describe('sendRegistrationMail', () => {
|
||||||
|
const data: {
|
||||||
|
email: string
|
||||||
|
nonce: string
|
||||||
|
locale: string
|
||||||
|
inviteCode?: string
|
||||||
|
} = {
|
||||||
|
email: 'user@example.org',
|
||||||
|
nonce: '123456',
|
||||||
|
locale: 'en',
|
||||||
|
inviteCode: 'welcome',
|
||||||
|
}
|
||||||
|
|
||||||
|
describe('with invite code', () => {
|
||||||
|
describe('English', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
data.locale = 'en'
|
||||||
|
data.inviteCode = 'welcome'
|
||||||
|
})
|
||||||
|
|
||||||
|
it('renders correctly', async () => {
|
||||||
|
await expect(sendRegistrationMail(data)).resolves.toMatchSnapshot()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('German', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
data.locale = 'de'
|
||||||
|
data.inviteCode = 'welcome'
|
||||||
|
})
|
||||||
|
|
||||||
|
it('renders correctly', async () => {
|
||||||
|
await expect(sendRegistrationMail(data)).resolves.toMatchSnapshot()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('without invite code', () => {
|
||||||
|
describe('English', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
data.locale = 'en'
|
||||||
|
delete data.inviteCode
|
||||||
|
})
|
||||||
|
|
||||||
|
it('renders correctly', async () => {
|
||||||
|
await expect(sendRegistrationMail(data)).resolves.toMatchSnapshot()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('German', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
data.locale = 'de'
|
||||||
|
delete data.inviteCode
|
||||||
|
})
|
||||||
|
|
||||||
|
it('renders correctly', async () => {
|
||||||
|
await expect(sendRegistrationMail(data)).resolves.toMatchSnapshot()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
35
backend/src/emails/sendResetPasswordMail.spec.ts
Normal file
35
backend/src/emails/sendResetPasswordMail.spec.ts
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
import { sendResetPasswordMail } from './sendEmail'
|
||||||
|
|
||||||
|
describe('sendResetPasswordMail', () => {
|
||||||
|
const data: {
|
||||||
|
email: string
|
||||||
|
nonce: string
|
||||||
|
locale: string
|
||||||
|
name: string
|
||||||
|
} = {
|
||||||
|
email: 'user@example.org',
|
||||||
|
nonce: '123456',
|
||||||
|
locale: 'en',
|
||||||
|
name: 'Jenny Rostock',
|
||||||
|
}
|
||||||
|
|
||||||
|
describe('English', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
data.locale = 'en'
|
||||||
|
})
|
||||||
|
|
||||||
|
it('renders correctly', async () => {
|
||||||
|
await expect(sendResetPasswordMail(data)).resolves.toMatchSnapshot()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('German', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
data.locale = 'de'
|
||||||
|
})
|
||||||
|
|
||||||
|
it('renders correctly', async () => {
|
||||||
|
await expect(sendResetPasswordMail(data)).resolves.toMatchSnapshot()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
31
backend/src/emails/sendWrongEmail.spec.ts
Normal file
31
backend/src/emails/sendWrongEmail.spec.ts
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
import { sendWrongEmail } from './sendEmail'
|
||||||
|
|
||||||
|
describe('sendWrongEmail', () => {
|
||||||
|
const data: {
|
||||||
|
email: string
|
||||||
|
locale: string
|
||||||
|
} = {
|
||||||
|
email: 'user@example.org',
|
||||||
|
locale: 'en',
|
||||||
|
}
|
||||||
|
|
||||||
|
describe('English', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
data.locale = 'en'
|
||||||
|
})
|
||||||
|
|
||||||
|
it('renders correctly', async () => {
|
||||||
|
await expect(sendWrongEmail(data)).resolves.toMatchSnapshot()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('German', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
data.locale = 'de'
|
||||||
|
})
|
||||||
|
|
||||||
|
it('renders correctly', async () => {
|
||||||
|
await expect(sendWrongEmail(data)).resolves.toMatchSnapshot()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
10
backend/src/emails/templates/emailVerification/html.pug
Normal file
10
backend/src/emails/templates/emailVerification/html.pug
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
extend ../layout.pug
|
||||||
|
|
||||||
|
block content
|
||||||
|
.content
|
||||||
|
p= t('emailVerification.introduction')
|
||||||
|
a.button(href=actionUrl)= t('buttons.verifyEmail')
|
||||||
|
p= t('emailVerification.doNotChange')
|
||||||
|
|
||||||
|
p= t('emailVerification.codeHint')
|
||||||
|
span= nonce
|
||||||
@ -0,0 +1 @@
|
|||||||
|
= `${t('subjects.newEmail')} ${APPLICATION_NAME}`
|
||||||
@ -3,12 +3,15 @@
|
|||||||
- var organizationUrl = ORGANIZATION_URL
|
- var organizationUrl = ORGANIZATION_URL
|
||||||
- var team = APPLICATION_NAME
|
- var team = APPLICATION_NAME
|
||||||
- var settingsUrl = settingsUrl
|
- var settingsUrl = settingsUrl
|
||||||
|
- var renderSettingsUrl = renderSettingsUrl
|
||||||
p= t('general.seeYou')
|
p= t('general.seeYou')
|
||||||
a.organization(href=organizationUrl)= team
|
a.organization(href=organizationUrl)= team
|
||||||
| !
|
| !
|
||||||
p= t('general.yourTeam', { team })
|
p= t('general.yourTeam', { team })
|
||||||
br
|
|
||||||
p= t('general.settingsHint')
|
if renderSettingsUrl
|
||||||
a.settings(href=settingsUrl)= t('general.settingsName')
|
br
|
||||||
| !
|
p= t('general.settingsHint')
|
||||||
|
a.settings(href=settingsUrl)= t('general.settingsName')
|
||||||
|
| !
|
||||||
|
|
||||||
|
|||||||
@ -50,6 +50,10 @@ a.button {
|
|||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
color: #17b53e;
|
||||||
|
}
|
||||||
|
|
||||||
.text-block {
|
.text-block {
|
||||||
margin-top: 20px;
|
margin-top: 20px;
|
||||||
color: #000000;
|
color: #000000;
|
||||||
|
|||||||
1
backend/src/emails/templates/includes/welcome.pug
Normal file
1
backend/src/emails/templates/includes/welcome.pug
Normal file
@ -0,0 +1 @@
|
|||||||
|
h2= `${t('general.welcome')} ${APPLICATION_NAME}!`
|
||||||
@ -13,11 +13,15 @@ html(lang=locale)
|
|||||||
.wf-force-outline-none[tabindex="-1"]:focus{outline:none;}
|
.wf-force-outline-none[tabindex="-1"]:focus{outline:none;}
|
||||||
style
|
style
|
||||||
include includes/webflow.css
|
include includes/webflow.css
|
||||||
|
|
||||||
|
- var name = name
|
||||||
body
|
body
|
||||||
div.container
|
div.container
|
||||||
include includes/header.pug
|
include includes/header.pug
|
||||||
include includes/salutation.pug
|
if name
|
||||||
|
include includes/salutation.pug
|
||||||
|
else
|
||||||
|
include includes/welcome.pug
|
||||||
|
|
||||||
.wrapper
|
.wrapper
|
||||||
block content
|
block content
|
||||||
|
|||||||
15
backend/src/emails/templates/registration/html.pug
Normal file
15
backend/src/emails/templates/registration/html.pug
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
extend ../layout.pug
|
||||||
|
|
||||||
|
block content
|
||||||
|
.content
|
||||||
|
p= t('registration.introduction')
|
||||||
|
a.button(href=actionUrl)= t('buttons.confirmEmail')
|
||||||
|
p= t('registration.codeHint')
|
||||||
|
span= nonce
|
||||||
|
p= t('registration.codeHintException')
|
||||||
|
|
||||||
|
p= t('registration.notYouStart')
|
||||||
|
a(href=ORGANIZATION_LINK)= APPLICATION_NAME
|
||||||
|
= t('registration.notYouEnd')
|
||||||
|
|
||||||
|
p= t('registration.ps')
|
||||||
1
backend/src/emails/templates/registration/subject.pug
Normal file
1
backend/src/emails/templates/registration/subject.pug
Normal file
@ -0,0 +1 @@
|
|||||||
|
= `${t('general.welcome')} ${APPLICATION_NAME}`
|
||||||
9
backend/src/emails/templates/resetPassword/html.pug
Normal file
9
backend/src/emails/templates/resetPassword/html.pug
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
extend ../layout.pug
|
||||||
|
|
||||||
|
block content
|
||||||
|
.content
|
||||||
|
p= t('resetPassword.introduction')
|
||||||
|
a.button(href=actionUrl)= t('buttons.confirmEmail')
|
||||||
|
p= t('resetPassword.ignore')
|
||||||
|
p= t('resetPassword.codeHint')
|
||||||
|
span= nonce
|
||||||
1
backend/src/emails/templates/resetPassword/subject.pug
Normal file
1
backend/src/emails/templates/resetPassword/subject.pug
Normal file
@ -0,0 +1 @@
|
|||||||
|
= `${t('subjects.resetPassword')} ${APPLICATION_NAME}`
|
||||||
10
backend/src/emails/templates/wrongEmail/html.pug
Normal file
10
backend/src/emails/templates/wrongEmail/html.pug
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
extend ../layout.pug
|
||||||
|
|
||||||
|
block content
|
||||||
|
.content
|
||||||
|
p= t('wrongEmail.introduction')
|
||||||
|
a.button(href=actionUrl)= t('buttons.tryAgain')
|
||||||
|
|
||||||
|
p= t('wrongEmail.ignoreStart')
|
||||||
|
a(href=ORGANIZATION_LINK)= APPLICATION_NAME
|
||||||
|
= t('wrongEmail.ignoreEnd')
|
||||||
1
backend/src/emails/templates/wrongEmail/subject.pug
Normal file
1
backend/src/emails/templates/wrongEmail/subject.pug
Normal file
@ -0,0 +1 @@
|
|||||||
|
= `${t('subjects.wrongEmail')} ${APPLICATION_NAME}`
|
||||||
@ -69,6 +69,7 @@ export default {
|
|||||||
)
|
)
|
||||||
return result.records.map((record) => ({
|
return result.records.map((record) => ({
|
||||||
name: record.get('user').properties.name,
|
name: record.get('user').properties.name,
|
||||||
|
locale: record.get('user').properties.locale,
|
||||||
...record.get('email').properties,
|
...record.get('email').properties,
|
||||||
}))
|
}))
|
||||||
})
|
})
|
||||||
|
|||||||
@ -71,14 +71,14 @@ describe('passwordReset', () => {
|
|||||||
|
|
||||||
describe('requestPasswordReset', () => {
|
describe('requestPasswordReset', () => {
|
||||||
const mutation = gql`
|
const mutation = gql`
|
||||||
mutation ($email: String!) {
|
mutation ($email: String!, $locale: String!) {
|
||||||
requestPasswordReset(email: $email)
|
requestPasswordReset(email: $email, locale: $locale)
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|
||||||
describe('with invalid email', () => {
|
describe('with invalid email', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
variables = { ...variables, email: 'non-existent@example.org' }
|
variables = { ...variables, email: 'non-existent@example.org', locale: 'de' }
|
||||||
})
|
})
|
||||||
|
|
||||||
it('resolves anyways', async () => {
|
it('resolves anyways', async () => {
|
||||||
@ -96,7 +96,7 @@ describe('passwordReset', () => {
|
|||||||
|
|
||||||
describe('with a valid email', () => {
|
describe('with a valid email', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
variables = { ...variables, email: 'user@example.org' }
|
variables = { ...variables, email: 'user@example.org', locale: 'de' }
|
||||||
})
|
})
|
||||||
|
|
||||||
it('resolves', async () => {
|
it('resolves', async () => {
|
||||||
|
|||||||
@ -50,14 +50,14 @@ afterEach(async () => {
|
|||||||
|
|
||||||
describe('Signup', () => {
|
describe('Signup', () => {
|
||||||
const mutation = gql`
|
const mutation = gql`
|
||||||
mutation ($email: String!, $inviteCode: String) {
|
mutation ($email: String!, $locale: String!, $inviteCode: String) {
|
||||||
Signup(email: $email, inviteCode: $inviteCode) {
|
Signup(email: $email, locale: $locale, inviteCode: $inviteCode) {
|
||||||
email
|
email
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
variables = { ...variables, email: 'someuser@example.org' }
|
variables = { ...variables, email: 'someuser@example.org', locale: 'de' }
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('unauthenticated', () => {
|
describe('unauthenticated', () => {
|
||||||
|
|||||||
@ -9,7 +9,11 @@ type Query {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Mutation {
|
type Mutation {
|
||||||
Signup(email: String!, inviteCode: String = null): EmailAddress
|
Signup(
|
||||||
|
email: String!
|
||||||
|
locale: String!
|
||||||
|
inviteCode: String = null
|
||||||
|
): EmailAddress
|
||||||
SignupVerification(
|
SignupVerification(
|
||||||
nonce: String!
|
nonce: String!
|
||||||
email: String!
|
email: String!
|
||||||
|
|||||||
@ -245,7 +245,7 @@ type Mutation {
|
|||||||
|
|
||||||
updateOnlineStatus(status: OnlineStatus!): Boolean!
|
updateOnlineStatus(status: OnlineStatus!): Boolean!
|
||||||
|
|
||||||
requestPasswordReset(email: String!): Boolean!
|
requestPasswordReset(email: String!, locale: String!): Boolean!
|
||||||
resetPassword(email: String!, nonce: String!, newPassword: String!): Boolean!
|
resetPassword(email: String!, nonce: String!, newPassword: String!): Boolean!
|
||||||
changePassword(oldPassword: String!, newPassword: String!): String!
|
changePassword(oldPassword: String!, newPassword: String!): String!
|
||||||
|
|
||||||
|
|||||||
@ -2,43 +2,41 @@
|
|||||||
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
||||||
/* eslint-disable @typescript-eslint/no-unsafe-call */
|
/* eslint-disable @typescript-eslint/no-unsafe-call */
|
||||||
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
||||||
import { sendMail } from '@middleware/helpers/email/sendMail'
|
|
||||||
import {
|
import {
|
||||||
signupTemplate,
|
sendRegistrationMail,
|
||||||
resetPasswordTemplate,
|
sendEmailVerification,
|
||||||
wrongAccountTemplate,
|
sendResetPasswordMail,
|
||||||
emailVerificationTemplate,
|
} from '@src/emails/sendEmail'
|
||||||
} from '@middleware/helpers/email/templateBuilder'
|
|
||||||
|
|
||||||
const sendSignupMail = async (resolve, root, args, context, resolveInfo) => {
|
const sendSignupMail = async (resolve, root, args, context, resolveInfo) => {
|
||||||
const { inviteCode } = args
|
const { inviteCode, locale } = args
|
||||||
const response = await resolve(root, args, context, resolveInfo)
|
const response = await resolve(root, args, context, resolveInfo)
|
||||||
const { email, nonce } = response
|
const { email, nonce } = response
|
||||||
if (nonce) {
|
if (nonce) {
|
||||||
// emails that already exist do not have a nonce
|
// emails that already exist do not have a nonce
|
||||||
if (inviteCode) {
|
await sendRegistrationMail({ email, nonce, locale, inviteCode })
|
||||||
await sendMail(signupTemplate({ email, variables: { nonce, inviteCode } }))
|
|
||||||
} else {
|
|
||||||
await sendMail(signupTemplate({ email, variables: { nonce } }))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
delete response.nonce
|
delete response.nonce
|
||||||
return response
|
return response
|
||||||
}
|
}
|
||||||
|
|
||||||
const sendPasswordResetMail = async (resolve, root, args, context, resolveInfo) => {
|
const sendPasswordResetMail = async (resolve, root, args, context, resolveInfo) => {
|
||||||
const { email } = args
|
const { email, locale } = args
|
||||||
const { email: userFound, nonce, name } = await resolve(root, args, context, resolveInfo)
|
const { email: userFound, nonce, name } = await resolve(root, args, context, resolveInfo)
|
||||||
const template = userFound ? resetPasswordTemplate : wrongAccountTemplate
|
if (userFound) {
|
||||||
await sendMail(template({ email, variables: { nonce, name } }))
|
await sendResetPasswordMail({ email, nonce, name, locale })
|
||||||
|
} else {
|
||||||
|
// this is an antifeature allowing unauthenticated users to spam any email with wrong-email notifications
|
||||||
|
// await sendWrongEmail({ email, locale })
|
||||||
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
const sendEmailVerificationMail = async (resolve, root, args, context, resolveInfo) => {
|
const sendEmailVerificationMail = async (resolve, root, args, context, resolveInfo) => {
|
||||||
const response = await resolve(root, args, context, resolveInfo)
|
const response = await resolve(root, args, context, resolveInfo)
|
||||||
const { email, nonce, name } = response
|
const { email, nonce, name, locale } = response
|
||||||
if (nonce) {
|
if (nonce) {
|
||||||
await sendMail(emailVerificationTemplate({ email, variables: { nonce, name } }))
|
await sendEmailVerification({ email, nonce, name, locale })
|
||||||
}
|
}
|
||||||
delete response.nonce
|
delete response.nonce
|
||||||
return response
|
return response
|
||||||
|
|||||||
@ -177,8 +177,8 @@ describe('authorization', () => {
|
|||||||
|
|
||||||
describe('access Signup', () => {
|
describe('access Signup', () => {
|
||||||
const signupMutation = gql`
|
const signupMutation = gql`
|
||||||
mutation ($email: String!, $inviteCode: String) {
|
mutation ($email: String!, $locale: String!, $inviteCode: String) {
|
||||||
Signup(email: $email, inviteCode: $inviteCode) {
|
Signup(email: $email, locale: $locale, inviteCode: $inviteCode) {
|
||||||
email
|
email
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -189,6 +189,7 @@ describe('authorization', () => {
|
|||||||
variables = {
|
variables = {
|
||||||
email: 'some@email.org',
|
email: 'some@email.org',
|
||||||
inviteCode: 'ABCDEF',
|
inviteCode: 'ABCDEF',
|
||||||
|
locale: 'de',
|
||||||
}
|
}
|
||||||
CONFIG.INVITE_REGISTRATION = false
|
CONFIG.INVITE_REGISTRATION = false
|
||||||
CONFIG.PUBLIC_REGISTRATION = false
|
CONFIG.PUBLIC_REGISTRATION = false
|
||||||
@ -231,6 +232,7 @@ describe('authorization', () => {
|
|||||||
variables = {
|
variables = {
|
||||||
email: 'some@email.org',
|
email: 'some@email.org',
|
||||||
inviteCode: 'ABCDEF',
|
inviteCode: 'ABCDEF',
|
||||||
|
locale: 'de',
|
||||||
}
|
}
|
||||||
CONFIG.INVITE_REGISTRATION = false
|
CONFIG.INVITE_REGISTRATION = false
|
||||||
CONFIG.PUBLIC_REGISTRATION = true
|
CONFIG.PUBLIC_REGISTRATION = true
|
||||||
@ -269,6 +271,7 @@ describe('authorization', () => {
|
|||||||
variables = {
|
variables = {
|
||||||
email: 'some@email.org',
|
email: 'some@email.org',
|
||||||
inviteCode: 'ABCDEF',
|
inviteCode: 'ABCDEF',
|
||||||
|
locale: 'de',
|
||||||
}
|
}
|
||||||
authenticatedUser = null
|
authenticatedUser = null
|
||||||
})
|
})
|
||||||
@ -288,6 +291,7 @@ describe('authorization', () => {
|
|||||||
variables = {
|
variables = {
|
||||||
email: 'some@email.org',
|
email: 'some@email.org',
|
||||||
inviteCode: 'no valid invite code',
|
inviteCode: 'no valid invite code',
|
||||||
|
locale: 'de',
|
||||||
}
|
}
|
||||||
authenticatedUser = null
|
authenticatedUser = null
|
||||||
})
|
})
|
||||||
|
|||||||
@ -59,7 +59,12 @@ describe('Request', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
it('delivers email to backend', () => {
|
it('delivers email to backend', () => {
|
||||||
const expected = expect.objectContaining({ variables: { email: 'mail@example.org' } })
|
const expected = expect.objectContaining({
|
||||||
|
variables: {
|
||||||
|
email: 'mail@example.org',
|
||||||
|
locale: 'en',
|
||||||
|
},
|
||||||
|
})
|
||||||
expect(mocks.$apollo.mutate).toHaveBeenCalledWith(expected)
|
expect(mocks.$apollo.mutate).toHaveBeenCalledWith(expected)
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -92,7 +97,12 @@ describe('Request', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
it('normalizes email to lower case letters', () => {
|
it('normalizes email to lower case letters', () => {
|
||||||
const expected = expect.objectContaining({ variables: { email: 'mail@gmail.com' } })
|
const expected = expect.objectContaining({
|
||||||
|
variables: {
|
||||||
|
email: 'mail@gmail.com',
|
||||||
|
locale: 'en',
|
||||||
|
},
|
||||||
|
})
|
||||||
expect(mocks.$apollo.mutate).toHaveBeenCalledWith(expected)
|
expect(mocks.$apollo.mutate).toHaveBeenCalledWith(expected)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@ -85,13 +85,13 @@ export default {
|
|||||||
},
|
},
|
||||||
async handleSubmit() {
|
async handleSubmit() {
|
||||||
const mutation = gql`
|
const mutation = gql`
|
||||||
mutation ($email: String!) {
|
mutation ($email: String!, $locale: String!) {
|
||||||
requestPasswordReset(email: $email)
|
requestPasswordReset(email: $email, locale: $locale)
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
try {
|
try {
|
||||||
const { email } = this
|
const { email } = this
|
||||||
await this.$apollo.mutate({ mutation, variables: { email } })
|
await this.$apollo.mutate({ mutation, variables: { email, locale: this.$i18n.locale() } })
|
||||||
this.submitted = true
|
this.submitted = true
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
|
|||||||
@ -36,8 +36,8 @@ import normalizeEmail from '~/components/utils/NormalizeEmail'
|
|||||||
import translateErrorMessage from '~/components/utils/TranslateErrorMessage'
|
import translateErrorMessage from '~/components/utils/TranslateErrorMessage'
|
||||||
|
|
||||||
export const SignupMutation = gql`
|
export const SignupMutation = gql`
|
||||||
mutation ($email: String!, $inviteCode: String) {
|
mutation ($email: String!, $locale: String!, $inviteCode: String) {
|
||||||
Signup(email: $email, inviteCode: $inviteCode) {
|
Signup(email: $email, locale: $locale, inviteCode: $inviteCode) {
|
||||||
email
|
email
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -140,7 +140,7 @@ export default {
|
|||||||
async onNextClick() {
|
async onNextClick() {
|
||||||
const { email } = this.formData
|
const { email } = this.formData
|
||||||
const { inviteCode = null } = this.sliderData.collectedInputData
|
const { inviteCode = null } = this.sliderData.collectedInputData
|
||||||
const variables = { email, inviteCode }
|
const variables = { email, inviteCode, locale: this.$i18n.locale() }
|
||||||
|
|
||||||
if (this.sliderData.collectedInputData.emailSend && !this.sendEmailAgain) {
|
if (this.sliderData.collectedInputData.emailSend && !this.sendEmailAgain) {
|
||||||
return true
|
return true
|
||||||
|
|||||||
@ -25,6 +25,9 @@ describe('Signup', () => {
|
|||||||
loading: false,
|
loading: false,
|
||||||
mutate: jest.fn().mockResolvedValue({ data: { Signup: { email: 'mail@example.org' } } }),
|
mutate: jest.fn().mockResolvedValue({ data: { Signup: { email: 'mail@example.org' } } }),
|
||||||
},
|
},
|
||||||
|
$i18n: {
|
||||||
|
locale: () => 'de',
|
||||||
|
},
|
||||||
}
|
}
|
||||||
propsData = {}
|
propsData = {}
|
||||||
})
|
})
|
||||||
@ -64,7 +67,7 @@ describe('Signup', () => {
|
|||||||
it('delivers email to backend', () => {
|
it('delivers email to backend', () => {
|
||||||
const expected = expect.objectContaining({
|
const expected = expect.objectContaining({
|
||||||
mutation: SignupMutation,
|
mutation: SignupMutation,
|
||||||
variables: { email: 'mAIL@exAMPLE.org', inviteCode: null },
|
variables: { email: 'mAIL@exAMPLE.org', locale: 'de', inviteCode: null },
|
||||||
})
|
})
|
||||||
expect(mocks.$apollo.mutate).toHaveBeenCalledWith(expected)
|
expect(mocks.$apollo.mutate).toHaveBeenCalledWith(expected)
|
||||||
})
|
})
|
||||||
|
|||||||
@ -70,8 +70,8 @@ import { SweetalertIcon } from 'vue-sweetalert-icons'
|
|||||||
import translateErrorMessage from '~/components/utils/TranslateErrorMessage'
|
import translateErrorMessage from '~/components/utils/TranslateErrorMessage'
|
||||||
|
|
||||||
export const SignupMutation = gql`
|
export const SignupMutation = gql`
|
||||||
mutation ($email: String!, $inviteCode: String) {
|
mutation ($email: String!, $locale: String!, $inviteCode: String) {
|
||||||
Signup(email: $email, inviteCode: $inviteCode) {
|
Signup(email: $email, locale: $locale, inviteCode: $inviteCode) {
|
||||||
email
|
email
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -121,7 +121,7 @@ export default {
|
|||||||
try {
|
try {
|
||||||
const response = await this.$apollo.mutate({
|
const response = await this.$apollo.mutate({
|
||||||
mutation: SignupMutation,
|
mutation: SignupMutation,
|
||||||
variables: { email, inviteCode: null },
|
variables: { email, locale: this.$i18n.locale(), inviteCode: null },
|
||||||
})
|
})
|
||||||
this.data = response.data
|
this.data = response.data
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user