Files
backend/internal/core/user_service.go

100 lines
2.6 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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)
}
// GetUserByID возвращает пользователя по его ID
func (s *UserService) GetUserByID(ctx context.Context, userID int) (*models.User, error) {
return s.Repo.GetUserByID(ctx, userID)
}
// 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
}