|
| 1 | +package usecase |
| 2 | + |
| 3 | +import ( |
| 4 | + "bytes" |
| 5 | + "context" |
| 6 | + "fmt" |
| 7 | + "html/template" |
| 8 | + "net/smtp" |
| 9 | + "os" |
| 10 | + |
| 11 | + "github.com/hammer-code/lms-be/domain" |
| 12 | + "github.com/sirupsen/logrus" |
| 13 | +) |
| 14 | + |
| 15 | +func (us *usecase) ForgotPassword(ctx context.Context, emailForgot domain.ForgotPassword) (err error) { |
| 16 | + user := domain.User{} |
| 17 | + err = us.dbTX.StartTransaction(ctx, func(txCtx context.Context) error { |
| 18 | + user, err = us.userRepo.FindByEmail(ctx, emailForgot.Email) |
| 19 | + if err != nil { |
| 20 | + logrus.Error("us.ForgotPassword: failed to get Email", err) |
| 21 | + return err |
| 22 | + } |
| 23 | + return nil |
| 24 | + }) |
| 25 | + |
| 26 | + if err != nil { |
| 27 | + logrus.Error("us.ForgotPassword: failed to get Email", err) |
| 28 | + return |
| 29 | + } |
| 30 | + |
| 31 | + resetToken, err := us.jwt.GenerateAccessToken(ctx, &user, 30) |
| 32 | + if err != nil { |
| 33 | + logrus.Error("us.ForgotPassword: failed to generate token", err) |
| 34 | + return |
| 35 | + } |
| 36 | + |
| 37 | + jwtData, err := us.jwt.VerifyToken(*resetToken) |
| 38 | + |
| 39 | + if err != nil { |
| 40 | + logrus.Error("us.ForgotPassword: failed to verify token", err) |
| 41 | + return |
| 42 | + } |
| 43 | + |
| 44 | + if err = us.userRepo.ForgotPassword(ctx, *resetToken, jwtData.ExpiresAt.Time, user); err != nil { |
| 45 | + logrus.Error("us.ForgotPassword: failed to save token", err) |
| 46 | + return |
| 47 | + } |
| 48 | + |
| 49 | + // link to reset password |
| 50 | + link := us.cfg.BASE_URL_FE + "/forgot_password?token=" + *resetToken |
| 51 | + |
| 52 | + htmlTmpl, err := os.ReadFile("./assets/reset_button_on_email.html") |
| 53 | + if err != nil { |
| 54 | + logrus.Error("us.ForgotPassword: failed to read template file", err) |
| 55 | + return |
| 56 | + } |
| 57 | + |
| 58 | + tmpl, err := template.New("reset_email").Parse(string(htmlTmpl)) |
| 59 | + if err != nil { |
| 60 | + logrus.Error("us.ForgotPassword: failed to parse template", err) |
| 61 | + return |
| 62 | + } |
| 63 | + |
| 64 | + var bodyBuffer bytes.Buffer |
| 65 | + if err = tmpl.Execute(&bodyBuffer, link); err != nil { |
| 66 | + logrus.Error("us.ForgotPassword: failed to execute template", err) |
| 67 | + return |
| 68 | + } |
| 69 | + |
| 70 | + subject := "Reset Password" |
| 71 | + mime := "MIME-version: 1.0;\nContent-Type: text/html; charset=\"UTF-8\";\n\n" |
| 72 | + message := []byte(fmt.Sprintf("To: %s\r\n"+ |
| 73 | + "Subject: %s\r\n"+ |
| 74 | + "%s\r\n"+ |
| 75 | + "%s\r\n", emailForgot.Email, subject, mime, bodyBuffer.String())) |
| 76 | + |
| 77 | + auth := smtp.PlainAuth("", us.cfg.SMTP_EMAIL, us.cfg.SMTP_PASSWORD, us.cfg.SMTP_HOST) |
| 78 | + |
| 79 | + host := fmt.Sprintf("%s:%s", us.cfg.SMTP_HOST, us.cfg.SMTP_PORT) |
| 80 | + if err := smtp.SendMail(host, auth, us.cfg.SMTP_EMAIL, []string{emailForgot.Email}, message); err != nil { |
| 81 | + return err |
| 82 | + } |
| 83 | + |
| 84 | + return nil |
| 85 | +} |
0 commit comments