95 lines
2.3 KiB
Go
95 lines
2.3 KiB
Go
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
|
|
}
|