package useCases import ( "RenewCMS/internal/domain/hash" "RenewCMS/internal/domain/mail" "RenewCMS/internal/domain/user" "errors" "fmt" "time" "github.com/google/uuid" ) type CreateUserUseCase struct { userRepository user.Repository hasher hash.Hasher mailRepository mail.Repository publicURL string } type CreateUserCommand struct { Username string Password string Email string } type MailValidationData struct { Host string VerificationCode string } func NewCreateUserUseCase(userRepository user.Repository, hasher hash.Hasher, mailRepository mail.Repository, publicURL string) *CreateUserUseCase { return &CreateUserUseCase{userRepository, hasher, mailRepository, publicURL} } func (g *CreateUserUseCase) CreateUser(createUser CreateUserCommand) (user.User, error) { if g.registrationClosed() { return user.User{}, user.ErrRegistrationClosed } rawUuid := uuid.NewString() hashedPassword, err := g.hasher.Hash(createUser.Password) if err != nil { return user.User{}, err } hashedVerificationCode, err := g.hasher.Hash(rawUuid) if err != nil { return user.User{}, err } createdUser, err := g.userRepository.Create(user.User{ Username: createUser.Username, Password: hashedPassword, PasswordResetCode: "", Email: createUser.Email, IsVerified: false, Role: user.RoleOwner, VerificationCode: hashedVerificationCode, VerificationExpiration: time.Now().Add(2 * time.Hour), }) if err != nil { return user.User{}, err } createdUser.VerificationCode = rawUuid if err := g.mailRepository.Send(createdUser.Email, "verification", MailValidationData{ Host: g.publicURL, VerificationCode: rawUuid, }); err != nil { sendErr := fmt.Errorf("failed to send verification email: %w", err) if deleteErr := g.userRepository.Delete(createdUser.ID); deleteErr != nil { return user.User{}, errors.Join(sendErr, deleteErr) } return user.User{}, sendErr } return createdUser, nil } func (g *CreateUserUseCase) IsRegistrationOpen() bool { return !g.registrationClosed() } func (g *CreateUserUseCase) registrationClosed() bool { for _, existingUser := range g.userRepository.GetAll() { if existingUser.IsVerified { return true } } return false }