package service import ( "context" "time" "erp-mvp/core-service/internal/auth" "erp-mvp/core-service/internal/models" "erp-mvp/core-service/internal/repository" "github.com/google/uuid" "github.com/sirupsen/logrus" ) type AuthService interface { Register(ctx context.Context, req *models.RegisterRequest) (*models.LoginResponse, error) Login(ctx context.Context, req *models.LoginRequest) (*models.LoginResponse, error) } type authService struct { orgRepo repository.OrganizationRepository userRepo repository.UserRepository jwtService *auth.JWTService logger *logrus.Logger } func NewAuthService(orgRepo repository.OrganizationRepository, userRepo repository.UserRepository, jwtService *auth.JWTService) AuthService { return &authService{ orgRepo: orgRepo, userRepo: userRepo, jwtService: jwtService, logger: logrus.New(), } } func (s *authService) Register(ctx context.Context, req *models.RegisterRequest) (*models.LoginResponse, error) { s.logger.Info("Starting registration process") // Проверяем, что пользователь с таким email не существует existingUser, err := s.userRepo.GetByEmail(ctx, req.UserEmail) if err == nil && existingUser != nil { s.logger.Error("User with this email already exists") return nil, &ValidationError{Message: "User with this email already exists"} } // Создаем организацию orgID := uuid.New() org := &models.Organization{ ID: orgID, Name: req.OrganizationName, Type: req.OrganizationType, Settings: models.JSON{"created_at": time.Now().Unix()}, CreatedAt: time.Now(), } s.logger.Info("Creating organization with ID: ", orgID) if err := s.orgRepo.Create(ctx, org); err != nil { s.logger.Error("Failed to create organization: ", err) return nil, err } s.logger.Info("Organization created successfully") // Хешируем пароль passwordHash, err := auth.HashPassword(req.UserPassword) if err != nil { s.logger.Error("Failed to hash password: ", err) return nil, err } s.logger.Info("Password hashed successfully") // Создаем пользователя userID := uuid.New() user := &models.User{ ID: userID, OrganizationID: orgID, Email: req.UserEmail, Role: "admin", // Первый пользователь становится админом CreatedAt: time.Now(), } s.logger.Info("Creating user with ID: ", userID) if err := s.userRepo.Create(ctx, user, passwordHash); err != nil { s.logger.Error("Failed to create user: ", err) return nil, err } s.logger.Info("User created successfully") // Генерируем JWT токен token, err := s.jwtService.GenerateToken(user.ID, org.ID, user.Email, user.Role) if err != nil { s.logger.Error("Failed to generate token: ", err) return nil, err } s.logger.Info("JWT token generated successfully") return &models.LoginResponse{ Token: token, User: models.UserResponse{ ID: user.ID, Email: user.Email, Role: user.Role, }, Organization: models.OrganizationResponse{ ID: org.ID, Name: org.Name, Type: org.Type, }, }, nil } func (s *authService) Login(ctx context.Context, req *models.LoginRequest) (*models.LoginResponse, error) { // Получаем пользователя по email user, err := s.userRepo.GetByEmail(ctx, req.Email) if err != nil { return nil, &ValidationError{Message: "Invalid email or password"} } // Проверяем пароль if !auth.CheckPassword(req.Password, user.PasswordHash) { return nil, &ValidationError{Message: "Invalid email or password"} } // Генерируем JWT токен token, err := s.jwtService.GenerateToken(user.ID, user.OrganizationID, user.Email, user.Role) if err != nil { return nil, err } // Получаем организацию для ответа org, err := s.orgRepo.GetByID(ctx, user.OrganizationID) if err != nil { return nil, err } return &models.LoginResponse{ Token: token, User: models.UserResponse{ ID: user.ID, Email: user.Email, Role: user.Role, }, Organization: models.OrganizationResponse{ ID: org.ID, Name: org.Name, Type: org.Type, }, }, nil } // ValidationError ошибка валидации type ValidationError struct { Message string } func (e *ValidationError) Error() string { return e.Message }