disabled html minfiy, added some headers and new templateS

alpha
alex 2024-01-20 22:54:39 +01:00
parent bf95daba4a
commit b8c2ec315e
9 changed files with 326 additions and 20 deletions

1
go.mod
View File

@ -12,6 +12,7 @@ require (
require (
github.com/gocql/gocql v0.0.0-20211015133455-b225f9b53fa1 // indirect
github.com/golang/snappy v0.0.4 // indirect
github.com/google/uuid v1.5.0 // indirect
github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.17 // indirect

2
go.sum
View File

@ -21,6 +21,8 @@ github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEW
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M=
github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU=
github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed h1:5upAirOpQc1Q53c0bnx2ufif5kANL7bfZWcc6VJWJd8=
github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4=
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=

View File

@ -7,7 +7,6 @@ import (
"clickandjoin.app/emailserver/modules/cache"
"clickandjoin.app/emailserver/modules/config"
gocnjhelper "git.ex.umbach.dev/ClickandJoin/go-cnj-helper"
"github.com/tdewolff/minify/v2/minify"
)
func readTemplatesConfig() {
@ -37,14 +36,16 @@ func loadTemplateFiles() {
if err != nil {
gocnjhelper.LogFatalf("Failed to read file, err: %s", err)
}
/*
minifiedHtml, err := minify.HTML(string(data))
minifiedHtml, err := minify.HTML(string(data))
if err != nil {
gocnjhelper.LogFatalf("Failed to minify html, err: %s", err)
} */
if err != nil {
gocnjhelper.LogFatalf("Failed to minify html, err: %s", err)
}
// cache.BodyTemplates[templateName] = []byte(minifiedHtml)
cache.BodyTemplates[templateName] = []byte(minifiedHtml)
cache.BodyTemplates[templateName] = []byte(data)
}
gocnjhelper.LogDebug("FINISHED IMPORTING TEMPLATE FILES")

View File

@ -27,11 +27,12 @@ type RabbitMq struct {
}
type Mail struct {
Host string
Username string
Password string
Port string
From string
Host string
Username string
Password string
Port string
FromName string
FromEmail string
}
type Templates struct {
@ -77,11 +78,12 @@ func LoadConfig() {
Password: os.Getenv("RABBITMQ_PASSWORD"),
},
Mail: Mail{
Host: os.Getenv("MAIL_HOST"),
Username: os.Getenv("MAIL_USERNAME"),
Password: os.Getenv("MAIL_PASSWORD"),
Port: os.Getenv("MAIL_PORT"),
From: os.Getenv("MAIL_FROM"),
Host: os.Getenv("MAIL_HOST"),
Username: os.Getenv("MAIL_USERNAME"),
Password: os.Getenv("MAIL_PASSWORD"),
Port: os.Getenv("MAIL_PORT"),
FromName: os.Getenv("MAIL_FROM_NAME"),
FromEmail: os.Getenv("MAIL_FROM_EMAIL"),
},
Templates: Templates{
FolderPath: os.Getenv("TEMPLATES_FOLDER_PATH"),

View File

@ -58,7 +58,8 @@ func MailMessagesHandling() {
// only for testing
if !strings.HasSuffix(mailMessage.UserMail, "@roese.dev") &&
!strings.HasSuffix(mailMessage.UserMail, "@umbach.dev") &&
!strings.HasSuffix(mailMessage.UserMail, "@kk-innovation.eu") {
!strings.HasSuffix(mailMessage.UserMail, "@kk-innovation.eu") &&
!strings.HasSuffix(mailMessage.UserMail, "@srv1.mail-tester.com") {
mailMessage.UserMail = "myprojects@roese.dev"
}

View File

@ -3,14 +3,17 @@ package structs
import (
"bytes"
"encoding/base64"
"fmt"
"html/template"
"net/smtp"
"strings"
"time"
"clickandjoin.app/emailserver/modules/cache"
"clickandjoin.app/emailserver/modules/config"
"clickandjoin.app/emailserver/modules/escaper"
gocnjhelper "git.ex.umbach.dev/ClickandJoin/go-cnj-helper"
"github.com/google/uuid"
)
type Mail struct {
@ -24,13 +27,15 @@ type Mail struct {
func (m *Mail) Send(body string) error {
cfg := config.Cfg.Mail
msg := "From: " + cfg.From + "\n" +
msg := "From: " + EncodeBase64(cfg.FromName) + " <" + cfg.FromEmail + ">\n" +
"To: " + strings.Join(m.To, ",") + "\n" +
"Subject: " + m.Subject + "\n" +
"Date: " + time.Now().Format("Mon, 02 Jan 2006 15:04:05 -0700") + "\n" +
"Message-ID: <" + uuid.New().String() + "@" + strings.Split(cfg.FromEmail, "@")[1] + ">\n" +
"MIME-version: 1.0;\nContent-Type: text/html; charset=\"UTF-8\";\n\n" +
body
err := smtp.SendMail(cfg.Host+":"+cfg.Port, cache.SmtpAuth, cfg.From, m.To, []byte(msg))
err := smtp.SendMail(cfg.Host+":"+cfg.Port, cache.SmtpAuth, cfg.FromEmail, m.To, []byte(msg))
if err != nil {
gocnjhelper.LogErrorf("smtp error: %s", err)
@ -84,7 +89,9 @@ func (m *Mail) RenderTemplate() (string, error) {
// The subject line of an email is an independent header and utf 8 must be set for it
// https://ncona.com/2011/06/using-utf-8-characters-on-an-e-mail-subject/
if m.LanguageId == "de" {
m.Subject = "=?utf-8?B?" + base64.StdEncoding.EncodeToString([]byte(m.Subject)) + "?="
//m.Subject = "=?utf-8?B?" + base64.StdEncoding.EncodeToString([]byte(m.Subject)) + "?="
m.Subject = EncodeBase64(m.Subject)
}
t := template.Must(template.New("").Parse(string(body)))
@ -97,3 +104,8 @@ func (m *Mail) RenderTemplate() (string, error) {
return buf.String(), nil
}
// https://ncona.com/2011/06/using-utf-8-characters-on-an-e-mail-subject/
func EncodeBase64(s string) string {
return fmt.Sprintf("=?utf-8?B?%s?=", base64.StdEncoding.EncodeToString([]byte(s)))
}

View File

@ -0,0 +1,119 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html lang="de">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<style>
body {
font-family: "Arial", sans-serif;
background-color: #f4f4f4;
margin: 0;
padding: 0;
}
table.container {
width: 100%;
max-width: 600px;
margin: 20px auto;
background-color: #ffffff;
border-radius: 8px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
padding: 20px;
}
table.content {
width: 100%;
}
h1 {
color: #333;
margin-bottom: 20px;
}
p {
color: #555;
margin: 0 0 15px;
}
.verification-code {
font-size: 24px;
font-weight: bold;
color: #3498db;
margin-top: 10px;
}
.booking-details {
margin-top: 20px;
padding: 10px;
background-color: #f4f4f4;
text-align: center;
border-radius: 8px;
}
.booking-details p {
margin: 5px 20px;
}
.booking-desc {
color: #000;
}
.booking-label {
font-weight: bold;
color: #3498db;
}
.footer {
margin-top: 20px;
color: #777;
font-size: 12px;
}
.confirm-button {
display: inline-block;
padding: 10px 15px;
background-color: #3498db;
color: #fff;
text-decoration: none;
border-radius: 5px;
margin-top: 20px;
}
.cancel-button {
display: inline-block;
padding: 10px 15px;
background-color: #e74c3c;
color: #fff;
text-decoration: none;
border-radius: 5px;
margin-top: 20px;
}
.divider {
margin: 20px 0;
border-bottom: 1px solid #ddd;
}
</style>
</head>
<body>
<table class="container" cellspacing="0" cellpadding="0">
<tr>
<td class="content">
<h1>%title%</h1>
<p>%header%</p>
<p>%text1%</p>
<a href="{{.verifyURL}}" class="confirm-button">%verifyButton%</a>
<div class="divider"></div>
<p>%cancelText%</p>
<a href="{{.cancelURL}}" class="cancel-button">%cancelButton%</a>
<div class="divider"></div>
<table class="booking-details">
<tr>
<td>
<p class="booking-label">%yourAppointment%</p>
<p class="booking-desc">%appointment1%</p>
<p class="booking-desc">%appointment2%</p>
<p class="booking-desc">%appointment3%</p>
</td>
</tr>
</table>
<div class="divider"></div>
<p>{{.address}}</p>
<p class="footer">%footer%</p>
<a class="footer" href="https://www.kk-innovation.eu">%dsgvo%</a>
</td>
</tr>
</table>
</body>
</html>

View File

@ -0,0 +1,96 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<style>
body {
font-family: "Arial", sans-serif;
background-color: #f4f4f4;
margin: 0;
padding: 0;
}
table.container {
width: 100%;
max-width: 600px;
margin: 20px auto;
background-color: #ffffff;
border-radius: 8px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
padding: 20px;
}
table.content {
width: 100%;
}
h1 {
color: #333;
margin-bottom: 20px;
}
p {
color: #555;
margin: 0 0 15px;
}
.verification-code {
font-size: 24px;
font-weight: bold;
color: #3498db;
margin-top: 10px;
}
.booking-details {
margin-top: 20px;
padding: 10px;
background-color: #f4f4f4;
text-align: center;
border-radius: 8px;
}
.booking-details p {
margin: 5px 20px;
}
.booking-desc {
color: #000;
}
.booking-label {
font-weight: bold;
color: #3498db;
}
.footer {
margin-top: 20px;
color: #777;
font-size: 12px;
}
.divider {
margin: 20px 0;
border-bottom: 1px solid #ddd;
}
</style>
</head>
<body>
<table class="container" cellspacing="0" cellpadding="0">
<tr>
<td class="content">
<h1>%title%</h1>
<p>%header%</p>
<p>%text1%</p>
<div class="divider"></div>
<table class="booking-details">
<tr>
<td>
<p class="booking-label">%yourAppointment%</p>
<p class="booking-desc">%appointment1%</p>
<p class="booking-desc">%appointment2%</p>
<p class="booking-desc">%appointment3%</p>
</td>
</tr>
</table>
<div class="divider"></div>
<p>{{.address}}</p>
<a class="footer" href="https://www.kk-innovation.eu">%dsgvo%</a>
</td>
</tr>
</table>
</body>
</html>

View File

@ -18,6 +18,78 @@
"de": "Bitte gebe diesen Code in der App ein"
}
},
"emailVerifyFailed": {
"mailSubject": {
"de": "Ihre Buchung wurde storniert"
},
"title": {
"de": "Ihre Buchung wurde storniert"
},
"header": {
"de": "Liebe(r) {{.name}},"
},
"text1": {
"de": "Ihre Buchung wurde storniert. Sie können gerne einen neuen Termin auf unserer Webseite festlegen."
},
"yourAppointment": {
"de": "Ihr Termin:"
},
"appointment1": {
"de": "{{.activityName}} bei {{.username}},"
},
"appointment2": {
"de": "{{.day}}, {{.dayNumber}}. {{.month}} {{.year}}"
},
"appointment3": {
"de": "von {{.startTime}} bis {{.endTime}} Uhr"
},
"footer": {
"de": "Vielen Dank, dass Sie unseren Service gewählt haben. Bei Fragen kontaktieren Sie uns gerne."
},
"dsgvo": {
"de": "Datenschutzerklärung"
}
},
"emailVerification2": {
"mailSubject": {
"de": "Bitte Bestätigen Sie Ihre Buchung"
},
"title": {
"de": "Buchungsbestätigung"
},
"header": {
"de": "Liebe(r) {{.name}},"
},
"text1": {
"de": "Ihre Buchung wurde erfolgreich empfangen und wartet auf Bestätigung. Bitte klicken Sie auf die untenstehende Schaltfläche, um den Vorgang abzuschließen."
},
"verifyButton": {
"de": "Buchung bestätigen"
},"cancelButton": {
"de": "Buchung stornieren"
},
"cancelText": {
"de": "Falls Sie Ihren Termin nicht wahrnehmen können, bitten wir Sie, den Termin zu stornieren."
},
"yourAppointment": {
"de": "Ihr Termin:"
},
"appointment1": {
"de": "{{.activityName}} bei {{.username}},"
},
"appointment2": {
"de": "{{.day}}, {{.dayNumber}}. {{.month}} {{.year}}"
},
"appointment3": {
"de": "von {{.startTime}} bis {{.endTime}} Uhr"
},
"footer": {
"de": "Vielen Dank, dass Sie unseren Service gewählt haben. Bei Fragen kontaktieren Sie uns gerne."
},
"dsgvo": {
"de": "Datenschutzerklärung"
}
},
"newUserSignIn": {
"mailSubject": {
"en": "A new sign-in was detected",