api/internal/api/user/service.go
2025-09-10 20:19:51 +03:00

129 lines
2.9 KiB
Go

package user
import (
"database/sql"
"errors"
"github.com/google/uuid"
log "github.com/sirupsen/logrus"
"merch-parser-api/internal/interfaces"
"merch-parser-api/internal/shared"
"time"
)
type service struct {
auth interfaces.Auth
repo UserRepo
utils interfaces.Utils
}
func newService(auth interfaces.Auth, repo UserRepo, utils interfaces.Utils) *service {
return &service{
auth: auth,
repo: repo,
utils: utils,
}
}
func (s *service) register(dto Register) error {
if !s.utils.IsEmail(dto.Email) {
return errors.New("email isn't valid")
}
if len(dto.Password) < 1 {
return errors.New("password can't be empty")
}
if len(dto.Username) > 255 {
return errors.New("username can't be longer than 255 characters")
}
hashedPass, err := s.utils.HashPassword(dto.Password)
if err != nil {
log.WithError(err).Error("User | Failed to hash password on register")
return err
}
user := User{
CreatedAt: time.Now().UTC(),
UpdatedAt: sql.NullTime{Valid: false},
DeletedAt: sql.NullTime{Valid: false},
Uuid: uuid.NewString(),
Username: dto.Username,
Password: hashedPass,
Email: dto.Email,
Verified: 0,
}
return s.repo.register(user)
}
func (s *service) get(userUuid string) (Info, error) {
user, err := s.repo.getByUuid(userUuid)
if err != nil {
log.WithError(err).Error("User | Failed to get user by uuid")
return Info{}, err
}
return Info{
Username: user.Username,
Email: user.Email,
CreatedAt: user.CreatedAt.String(),
}, err
}
func (s *service) update(userUuid string, update Update) error {
user := make(map[string]any)
if update.Username != "" {
user["username"] = update.Username
}
if update.Email != "" {
user["email"] = update.Email
}
user["updated_at"] = time.Now().UTC()
user["uuid"] = userUuid
return s.repo.update(user)
}
func (s *service) delete(userUuid string) error {
return s.repo.delete(userUuid)
}
func (s *service) login(login Login) (shared.AuthData, error) {
if !s.utils.IsEmail(login.Email) {
return shared.AuthData{}, errors.New("email isn't valid")
}
if len(login.Password) < 1 {
return shared.AuthData{}, errors.New("password can't be empty")
}
user, err := s.repo.getUserByEmail(login.Email)
if err != nil {
log.WithError(err).Error("User | Failed to get user by email")
return shared.AuthData{}, errors.New("invalid email or password")
}
if err = s.utils.ComparePasswords(user.Password, login.Password); err != nil {
return shared.AuthData{}, errors.New("invalid email or password")
}
authData, err := s.auth.Login(user.Uuid)
if err != nil {
log.WithError(err).Error("User | Failed to generate auth data")
return shared.AuthData{}, err
}
return authData, nil
}
func (s *service) logout(userUuid, refreshUuid string) error {
return s.auth.Logout(userUuid, refreshUuid)
}
func (s *service) refresh(userUuid, refreshUuid string) (shared.AuthData, error) {
return s.auth.Refresh(userUuid, refreshUuid)
}