From 4d9b73cb34b32d3d73f9296bac00934a07cae2c3 Mon Sep 17 00:00:00 2001 From: Fedorov Vladimir Date: Mon, 29 Jun 2026 23:34:09 +0700 Subject: [PATCH] add email sender and send email with password --- cmd/evening_detective_server/main.go | 8 +- internal/modules/email_sender/interface.go | 13 +++ internal/modules/email_sender/sender.go | 94 ++++++++++++++++++++++ internal/services/users_service/service.go | 15 ++++ 4 files changed, 129 insertions(+), 1 deletion(-) create mode 100644 internal/modules/email_sender/interface.go create mode 100644 internal/modules/email_sender/sender.go diff --git a/cmd/evening_detective_server/main.go b/cmd/evening_detective_server/main.go index 5dc706a..273c78e 100644 --- a/cmd/evening_detective_server/main.go +++ b/cmd/evening_detective_server/main.go @@ -4,6 +4,7 @@ import ( "context" _ "embed" "evening_detective_server/internal/app" + "evening_detective_server/internal/modules/email_sender" "evening_detective_server/internal/modules/password_generator" "evening_detective_server/internal/repos/users_repo" "evening_detective_server/internal/services/users_service" @@ -43,7 +44,12 @@ func main() { usersRepo := users_repo.NewUserRepo(dbpool) passwordGenerator := password_generator.NewGenerator(8) - usersService := users_service.NewUsersService(usersRepo, passwordGenerator) + smtpHost := os.Getenv("SMTP_HOST") + smtpPort := os.Getenv("SMTP_PORT") + smtpUser := os.Getenv("SMTP_USER") + smtpPassword := os.Getenv("SMTP_PASSWORD") + emailSender := email_sender.NewSender(smtpHost, smtpPort, smtpUser, smtpPassword) + usersService := users_service.NewUsersService(usersRepo, passwordGenerator, emailSender) // Create a listener on TCP port lis, err := net.Listen("tcp", ":8080") diff --git a/internal/modules/email_sender/interface.go b/internal/modules/email_sender/interface.go new file mode 100644 index 0000000..08ded4f --- /dev/null +++ b/internal/modules/email_sender/interface.go @@ -0,0 +1,13 @@ +package email_sender + +import "context" + +type Message struct { + To string + Subject string + Body string +} + +type IEmailSender interface { + Send(ctx context.Context, message Message) error +} diff --git a/internal/modules/email_sender/sender.go b/internal/modules/email_sender/sender.go new file mode 100644 index 0000000..62cf494 --- /dev/null +++ b/internal/modules/email_sender/sender.go @@ -0,0 +1,94 @@ +package email_sender + +import ( + "context" + "crypto/tls" + "fmt" + "net/smtp" +) + +type sender struct { + smtpHost string + smtpPort string + smtpUser string + smtpPassword string +} + +func NewSender( + smtpHost string, + smtpPort string, + smtpUser string, + smtpPassword string, +) IEmailSender { + return &sender{ + smtpHost: smtpHost, + smtpPort: smtpPort, + smtpUser: smtpUser, + smtpPassword: smtpPassword, + } +} + +func (s *sender) Send(_ context.Context, message Message) error { + emailMessage := []byte(fmt.Sprintf( + "To: %s\r\n"+ + "Subject: %s\r\n"+ + "MIME-Version: 1.0\r\n"+ + "Content-Type: text/plain; charset=utf-8\r\n"+ + "\r\n"+ + "%s\r\n", + message.To, + message.Subject, + message.Body, + )) + + // Настраиваем TLS + tlsConfig := &tls.Config{ + ServerName: s.smtpHost, + } + + // Подключаемся к серверу + conn, err := tls.Dial("tcp", s.smtpHost+":"+s.smtpPort, tlsConfig) + if err != nil { + return err + } + defer conn.Close() + + // Создаем SMTP клиент + client, err := smtp.NewClient(conn, s.smtpHost) + if err != nil { + return err + } + defer client.Quit() + + // Аутентификация + auth := smtp.PlainAuth("", s.smtpUser, s.smtpPassword, s.smtpHost) + if err = client.Auth(auth); err != nil { + return err + } + + // Указываем отправителя + if err = client.Mail(s.smtpUser); err != nil { + return err + } + + // Указываем получателя + if err = client.Rcpt(message.To); err != nil { + return err + } + + // Отправляем данные письма + w, err := client.Data() + if err != nil { + return err + } + _, err = w.Write(emailMessage) + if err != nil { + return err + } + err = w.Close() + if err != nil { + return err + } + + return nil +} diff --git a/internal/services/users_service/service.go b/internal/services/users_service/service.go index ed25645..37a261f 100644 --- a/internal/services/users_service/service.go +++ b/internal/services/users_service/service.go @@ -2,8 +2,10 @@ package users_service import ( "context" + "evening_detective_server/internal/modules/email_sender" "evening_detective_server/internal/modules/password_generator" "evening_detective_server/internal/repos/users_repo" + "fmt" "golang.org/x/crypto/bcrypt" ) @@ -11,15 +13,18 @@ import ( type UsersService struct { usersRepo *users_repo.UsersRepo passwordGenerator password_generator.IPasswordGenerator + emailSender email_sender.IEmailSender } func NewUsersService( usersRepo *users_repo.UsersRepo, passwordGenerator password_generator.IPasswordGenerator, + emailSender email_sender.IEmailSender, ) *UsersService { return &UsersService{ usersRepo: usersRepo, passwordGenerator: passwordGenerator, + emailSender: emailSender, } } @@ -43,5 +48,15 @@ func (s *UsersService) AddUser( string(hashedPassword), "user", ) + if err != nil { + return err + } + + err = s.emailSender.Send(ctx, email_sender.Message{ + To: email, + Subject: "Приветствую тебя, детектив!", + Body: fmt.Sprintf("Вот твой пароль для входа в систему: %s", password), + }) + return err }