diff --git a/internal/app/factory.go b/internal/app/factory.go index 9e0277c..3595250 100644 --- a/internal/app/factory.go +++ b/internal/app/factory.go @@ -29,6 +29,7 @@ func AppFactory() *fiber.App { app.Post("/contact-us", ContactUsHandler) app.Post("/welcome", WelcomeHandler) + app.Post("/password-reset", PasswordResetHandler) return app } diff --git a/internal/app/handler.go b/internal/app/handler.go index 3a9355f..7e18ecc 100644 --- a/internal/app/handler.go +++ b/internal/app/handler.go @@ -41,3 +41,21 @@ func WelcomeHandler(c *fiber.Ctx) error { } return c.SendStatus(fiber.StatusAccepted) } + +func PasswordResetHandler(c *fiber.Ctx) error { + c.Accepts("application/json") + + var payload PasswordResetInput + + err := c.BodyParser(&payload) + if err != nil { + slog.Error(err.Error()) + return fiber.NewError(fiber.StatusUnprocessableEntity) + } + err = service.SendPasswordResetMail(payload) + if err != nil { + slog.Error(err.Error()) + return fiber.NewError(fiber.StatusBadRequest) + } + return c.SendStatus(fiber.StatusAccepted) +} diff --git a/internal/app/service.go b/internal/app/service.go index 6ad5969..e63e74b 100644 --- a/internal/app/service.go +++ b/internal/app/service.go @@ -219,3 +219,69 @@ func (s *Service) SendWelcomeMail(payload WelcomeInput) error { body.Reset() return nil } + +func (s *Service) SendPasswordResetMail(payload PasswordResetInput) error { + mimeHeaders := "MIME-version: 1.0;\nContent-Type: text/html; charset=\"UTF-8\";\n\n" + body := bytes.NewBuffer(nil) + + h := hermes.Hermes{ + Product: hermes.Product{ + Name: "WeCoach", + Link: "http://wecoach.ai", + Logo: "http://wecoach.ai/static/images/logo.png", + }, + } + templatePath := "/tmp/password-reset.html" + templateContext := make(map[string]string) + email := hermes.Email{ + Body: hermes.Body{ + Name: payload.Name, + Intros: []string{ + "You have received this email because a password reset request for Hermes account was received.", + }, + Actions: []hermes.Action{ + { + Instructions: "Click the below button to reset your password.", + Button: hermes.Button{ + Color: "#DC4D2F", + Text: "Password reset", + Link: payload.Link, + }, + }, + }, + Outros: []string{ + "If you did not request a password reset, no further action is required on your part.", + }, + Signature: "Thanks", + }, + } + body.Write([]byte(fmt.Sprintf("Subject: %s \n%s\n\n", "Password Reset Email", mimeHeaders))) + + emailBody, err := h.GenerateHTML(email) + if err != nil { + slog.Error(err.Error()) + return err + } + + err = os.WriteFile(templatePath, []byte(emailBody), 0666) + if err != nil { + slog.Error(err.Error()) + return err + } + + tpl, _ := template.ParseFiles(templatePath) + err = tpl.Execute(body, templateContext) + if err != nil { + slog.Error(err.Error()) + return err + } + serverAuth := smtp.PlainAuth(s.Config.SMTPIdentity, s.Config.SMTPUsername, s.Config.SMTPPassword, s.Config.SMTPHost) + + err = smtp.SendMail(s.Config.SMTPHost+":"+s.Config.SMTPPort, serverAuth, s.Config.SMTPUsername, []string{payload.Email}, body.Bytes()) + if err != nil { + slog.Error(err.Error()) + return err + } + body.Reset() + return nil +} diff --git a/internal/app/types.go b/internal/app/types.go index abdc942..c700e15 100644 --- a/internal/app/types.go +++ b/internal/app/types.go @@ -13,3 +13,9 @@ type WelcomeInput struct { UserType string Email string } + +type PasswordResetInput struct { + Name string + Link string + Email string +}