66 lines
1.9 KiB
Go
66 lines
1.9 KiB
Go
package core
|
||
|
||
import (
|
||
"context"
|
||
"errors"
|
||
"regexp"
|
||
|
||
"gitea.mrixs.me/minecraft-platform/backend/internal/database"
|
||
"gitea.mrixs.me/minecraft-platform/backend/internal/models"
|
||
"github.com/google/uuid"
|
||
"golang.org/x/crypto/bcrypt"
|
||
)
|
||
|
||
var (
|
||
ErrInvalidUsername = errors.New("invalid username format or length")
|
||
ErrInvalidEmail = errors.New("invalid email format")
|
||
ErrPasswordTooShort = errors.New("password is too short (minimum 8 characters)")
|
||
)
|
||
|
||
// Регулярное выражение для валидации username
|
||
var usernameRegex = regexp.MustCompile(`^[a-zA-Z0-9_]{3,16}$`)
|
||
|
||
// Регулярное выражение для валидации email (упрощенное, но эффективное)
|
||
var emailRegex = regexp.MustCompile(`^[a-zA-Z0-9._%+\-]+@[a-zA-Z0-9.\-]+\.[a-zA-Z]{2,}$`)
|
||
|
||
type UserService struct {
|
||
Repo *database.UserRepository
|
||
}
|
||
|
||
// RegisterNewUser выполняет полный алгоритм регистрации
|
||
func (s *UserService) RegisterNewUser(ctx context.Context, req models.RegisterRequest) error {
|
||
// Шаг 2 из ТЗ: Валидация
|
||
if !usernameRegex.MatchString(req.Username) {
|
||
return ErrInvalidUsername
|
||
}
|
||
if !emailRegex.MatchString(req.Email) {
|
||
return ErrInvalidEmail
|
||
}
|
||
if len(req.Password) < 8 {
|
||
return ErrPasswordTooShort
|
||
}
|
||
|
||
// Шаг 5 из ТЗ: Генерация хеша пароля
|
||
passwordHash, err := bcrypt.GenerateFromPassword([]byte(req.Password), 12) // Стоимость 12, как в ТЗ
|
||
if err != nil {
|
||
return err
|
||
}
|
||
|
||
// Шаг 6 из ТЗ: Генерация UUID
|
||
userUUID, err := uuid.NewRandom()
|
||
if err != nil {
|
||
return err
|
||
}
|
||
|
||
user := &models.User{
|
||
UUID: userUUID,
|
||
Username: req.Username,
|
||
Email: req.Email,
|
||
PasswordHash: string(passwordHash),
|
||
Role: "user", // По умолчанию
|
||
}
|
||
|
||
// Вызываем метод репозитория для сохранения в БД
|
||
return s.Repo.CreateUserTx(ctx, user)
|
||
}
|