95 lines
2.4 KiB
Go
95 lines
2.4 KiB
Go
package core
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
"log"
|
|
"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)")
|
|
)
|
|
|
|
var usernameRegex = regexp.MustCompile(`^[a-zA-Z0-9_]{3,16}$`)
|
|
|
|
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 {
|
|
if !usernameRegex.MatchString(req.Username) {
|
|
return ErrInvalidUsername
|
|
}
|
|
if !emailRegex.MatchString(req.Email) {
|
|
return ErrInvalidEmail
|
|
}
|
|
if len(req.Password) < 8 {
|
|
return ErrPasswordTooShort
|
|
}
|
|
|
|
passwordHash, err := bcrypt.GenerateFromPassword([]byte(req.Password), 12)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
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)
|
|
}
|
|
|
|
// ValidateJoinRequest проверяет запрос на присоединение к серверу.
|
|
func (s *AuthService) ValidateJoinRequest(ctx context.Context, req models.JoinRequest) error {
|
|
var uuidStr string
|
|
if len(req.SelectedProfile) == 32 {
|
|
uuidStr = fmt.Sprintf("%s-%s-%s-%s-%s",
|
|
req.SelectedProfile[0:8],
|
|
req.SelectedProfile[8:12],
|
|
req.SelectedProfile[12:16],
|
|
req.SelectedProfile[16:20],
|
|
req.SelectedProfile[20:32],
|
|
)
|
|
} else {
|
|
return errors.New("invalid profile UUID format")
|
|
}
|
|
|
|
userUUID, err := uuid.Parse(uuidStr)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to parse profile UUID: %w", err)
|
|
}
|
|
|
|
err = s.UserRepo.ValidateAccessToken(ctx, req.AccessToken, userUUID)
|
|
if err != nil {
|
|
if errors.Is(err, database.ErrTokenNotFound) {
|
|
return ErrInvalidCredentials
|
|
}
|
|
return err
|
|
}
|
|
|
|
log.Printf("User %s successfully joined server with serverId %s", userUUID, req.ServerID)
|
|
|
|
return nil
|
|
}
|