package useCases import ( "RenewCMS/internal/domain/audit" "RenewCMS/internal/domain/hash" "RenewCMS/internal/domain/mail" "RenewCMS/internal/domain/user" "context" "log" "time" "github.com/google/uuid" ) type RequestPasswordResetUseCase struct { userRepository user.Repository hasher hash.Hasher mailRepository mail.Repository publicURL string recorder audit.Recorder } type MailPasswordResetData struct { Host string VerificationCode string Email string } func NewRequestPasswordResetUseCase(userRepository user.Repository, hasher hash.Hasher, mailRepository mail.Repository, publicURL string, recorder audit.Recorder) *RequestPasswordResetUseCase { return &RequestPasswordResetUseCase{userRepository, hasher, mailRepository, publicURL, recorder} } func (g *RequestPasswordResetUseCase) RequestPasswordReset(ctx context.Context, email string) error { foundUser, err := g.userRepository.GetByEmail(email) if err != nil { return nil } rawCode := uuid.NewString() hashedCode, err := g.hasher.Hash(rawCode) if err != nil { log.Println("error when hashing the password reset code:", err) return nil } if _, err := g.userRepository.UpdatePasswordResetCode(foundUser.ID, hashedCode, time.Now().Add(time.Hour)); err != nil { log.Println("error when calling UpdatePasswordResetCode to store the password reset code:", err) return nil } g.recordRequest(ctx, foundUser) if err := g.mailRepository.Send(foundUser.Email, "password-reset", MailPasswordResetData{ Host: g.publicURL, VerificationCode: rawCode, Email: foundUser.Email, }); err != nil { log.Println("error when Send-ing the password reset mail:", err) return nil } return nil } func (g *RequestPasswordResetUseCase) recordRequest(ctx context.Context, requester user.User) { event := audit.NewEvent(audit.ActionPasswordResetRequest, audit.CategoryAuth) event.Actor = audit.UserActor(requester) event.Security = true g.recorder.Record(ctx, event) }