added mail functionality

This commit is contained in:
$(pass /github/name)
2024-07-03 12:35:41 +02:00
parent 6d34d99835
commit 96f008d67e
10 changed files with 132 additions and 24 deletions

View File

@@ -18,9 +18,19 @@ type AuthenticationConfig struct {
CSRFSecret string
}
type SMTPConfig struct {
Host string `json:"Host"`
User string `json:"User"`
Password string `json:"Password"`
Mailtype string `json:"Mailtype"`
AdminEmail string `json:"AdminEmail"`
Port int `json:"Port"`
}
type Config struct {
DB DatabaseConfig `json:"db"`
Auth AuthenticationConfig
SMTP SMTPConfig `json:"smtp"`
}
var (

View File

@@ -11,11 +11,12 @@ import (
)
type UserController struct {
service services.UserService
service services.UserService
emailService services.EmailService
}
func NewUserController(service services.UserService) *UserController {
return &UserController{service}
func NewUserController(service services.UserService, emailService *services.EmailService) *UserController {
return &UserController{service, *emailService}
}
func (uc *UserController) RegisterUser(w http.ResponseWriter, r *http.Request) {
@@ -32,6 +33,15 @@ func (uc *UserController) RegisterUser(w http.ResponseWriter, r *http.Request) {
logger.Error.Printf("Couldn't register User: %v", err)
return
}
// Send welcome email to the user
if err := uc.emailService.SendWelcomeEmail(user); err != nil {
logger.Error.Printf("Failed to send welcome email to user: %v", err)
}
// Notify admin of new user registration
if err := uc.emailService.NotifyAdminOfNewUser(user.Email); err != nil {
logger.Error.Printf("Failed to notify admin of new user registration: %v", err)
}
w.WriteHeader(http.StatusCreated)
}

View File

@@ -27,18 +27,17 @@ func initializeDB(dbPath string, schemaPath string) error {
return nil
}
func Connect() *sql.DB {
cfg := config.LoadConfig()
_, err := os.Stat(cfg.DB.DBPath)
func Connect(DBcfg config.DatabaseConfig) *sql.DB {
_, err := os.Stat(DBcfg.DBPath)
if os.IsNotExist(err) {
initErr := initializeDB(cfg.DB.DBPath, "internal/database/schema.sql")
initErr := initializeDB(DBcfg.DBPath, "internal/database/schema.sql")
if initErr != nil {
logger.Error.Fatalf("Couldn't create database: %v", initErr)
}
logger.Info.Println("Created new database")
}
db, err := sql.Open("sqlite3", cfg.DB.DBPath)
db, err := sql.Open("sqlite3", DBcfg.DBPath)
if err != nil {
logger.Error.Fatal(err)
}

View File

@@ -1,6 +1,7 @@
package server
import (
"GoMembership/internal/config"
"GoMembership/internal/controllers"
"GoMembership/internal/database"
"GoMembership/internal/middlewares"
@@ -14,12 +15,15 @@ import (
)
func Run() {
db := database.Connect()
cfg := config.LoadConfig()
db := database.Connect(cfg.DB)
defer db.Close()
emailService := services.NewEmailService(cfg.SMTP.Host, cfg.SMTP.Port, cfg.SMTP.User, cfg.SMTP.Password, cfg.SMTP.AdminEmail)
userRepo := repositories.NewUserRepository(db)
userService := services.NewUserService(userRepo)
userController := controllers.NewUserController(userService)
userController := controllers.NewUserController(userService, emailService)
router := mux.NewRouter()
// router.Handle("/csrf-token", middlewares.GenerateCSRFTokenHandler()).Methods("GET")

View File

@@ -0,0 +1,77 @@
package services
import (
"GoMembership/internal/models"
"GoMembership/pkg/logger"
"bytes"
"gopkg.in/gomail.v2"
"html/template"
)
type EmailService struct {
dialer *gomail.Dialer
adminEmail string
}
func NewEmailService(host string, port int, username, password, adminEmail string) *EmailService {
dialer := gomail.NewDialer(host, port, username, password)
return &EmailService{dialer: dialer, adminEmail: adminEmail}
}
func (s *EmailService) SendEmail(to string, subject string, body string) error {
msg := gomail.NewMessage()
msg.SetHeader("From", s.dialer.Username)
msg.SetHeader("To", to)
msg.SetHeader("Subject", subject)
msg.SetBody("text/html", body)
if err := s.dialer.DialAndSend(msg); err != nil {
logger.Error.Printf("Could not send email to %s: %v", to, err)
return err
}
logger.Info.Printf("Email sent to %s", to)
return nil
}
func ParseTemplate(path string, data interface{}) (string, error) {
// Read the email template file
tpl, err := template.ParseFiles(path)
if err != nil {
logger.Error.Printf("Failed to parse email template: %v", err)
return "", err
}
// Buffer to hold the rendered template
var tplBuffer bytes.Buffer
if err := tpl.Execute(&tplBuffer, data); err != nil {
logger.Error.Printf("Failed to execute email template: %v", err)
return "", err
}
return tplBuffer.String(), nil
}
func (s *EmailService) SendWelcomeEmail(user models.User) error {
// Prepare data to be injected into the template
data := struct {
FirstName string
LastName string
}{
FirstName: user.FirstName,
LastName: user.LastName,
}
subject := "Willkommen beim Dörpsmobil Hasloh e.V."
body, err := ParseTemplate("internal/templates/mail_welcome.html", data)
if err != nil {
logger.Error.Print("Couldn't send welcome mail")
return err
}
return s.SendEmail(user.Email, subject, body)
}
func (s *EmailService) NotifyAdminOfNewUser(userEmail string) error {
subject := "New User Registration"
body := "<p>A new user has registered with the email: " + userEmail + "</p>"
return s.SendEmail(s.adminEmail, subject, body)
}

View File

@@ -3,8 +3,7 @@ package utils
import "regexp"
func IsEmailValid(email string) bool {
regex := `^[a-z0-9._%+\-]+@[a-z0-9.\-]+\.[a-z]{2,}$`
re := regexp.MustCompile(regex)
return re.MatchString(email)
regex := `^[a-z0-9._%+\-]+@[a-z0-9.\-]+\.[a-z]{2,}$`
re := regexp.MustCompile(regex)
return re.MatchString(email)
}