744 lines
22 KiB
Go
744 lines
22 KiB
Go
package service
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
"strings"
|
|
|
|
"github.com/Caknoooo/go-gin-clean-starter/database/entities"
|
|
authDto "github.com/Caknoooo/go-gin-clean-starter/modules/auth/dto"
|
|
authRepo "github.com/Caknoooo/go-gin-clean-starter/modules/auth/repository"
|
|
authService "github.com/Caknoooo/go-gin-clean-starter/modules/auth/service"
|
|
clientrepository "github.com/Caknoooo/go-gin-clean-starter/modules/client/repository"
|
|
rolerepository "github.com/Caknoooo/go-gin-clean-starter/modules/role/repository"
|
|
"github.com/Caknoooo/go-gin-clean-starter/modules/user/dto"
|
|
"github.com/Caknoooo/go-gin-clean-starter/modules/user/repository"
|
|
warehouserepository "github.com/Caknoooo/go-gin-clean-starter/modules/warehouse/repository"
|
|
pkgconstants "github.com/Caknoooo/go-gin-clean-starter/pkg/constants"
|
|
pkgdto "github.com/Caknoooo/go-gin-clean-starter/pkg/dto"
|
|
"github.com/Caknoooo/go-gin-clean-starter/pkg/utils"
|
|
"github.com/google/uuid"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
type UserService interface {
|
|
Create(ctx context.Context, req dto.UserCreateRequest) (dto.UserResponse, error)
|
|
Register(ctx context.Context, req dto.UserCreateRequest) (dto.UserResponse, error)
|
|
GetUserById(ctx context.Context, userId string) (dto.UserResponse, error)
|
|
Verify(ctx context.Context, req dto.UserLoginRequest) (authDto.TokenResponse, error)
|
|
SendVerificationEmail(ctx context.Context, req dto.SendVerificationEmailRequest) error
|
|
VerifyEmail(ctx context.Context, req dto.VerifyEmailRequest) (dto.VerifyEmailResponse, error)
|
|
Update(ctx context.Context, req dto.UserUpdateRequest, userId string) (dto.UserUpdateResponse, error)
|
|
Delete(ctx context.Context, userId string) error
|
|
RefreshToken(ctx context.Context, req authDto.RefreshTokenRequest) (authDto.TokenResponse, error)
|
|
SwitchRole(ctx context.Context, userId string, req dto.SwitchRoleRequest) (authDto.TokenResponse, error)
|
|
GetAll(ctx context.Context) ([]dto.UserResponse, error)
|
|
GetUserWarehouses(ctx context.Context, userId string) ([]dto.UserResponse, error)
|
|
SwitchWarehouse(ctx context.Context, userId string, req dto.SwitchWarehouseRequest) (authDto.TokenResponse, error)
|
|
// AssignWarehouseToUser(ctx context.Context, userId string, warehouseIds []string) error
|
|
// RemoveWarehouseFromUser(ctx context.Context, userId string, warehouseIds []string) error
|
|
// ClearUserWarehouses(ctx context.Context, userId string) error
|
|
AssignWarehousesReplace(ctx context.Context, userId string, warehouseIds []string) error
|
|
AssignWarehouse(ctx context.Context, userId string, warehouseId string) error
|
|
RemoveWarehouse(ctx context.Context, userId string, warehouseId string) error
|
|
BulkCreate(ctx context.Context, req dto.BulkCreateUserRequest) error
|
|
}
|
|
|
|
type userService struct {
|
|
clientRepository clientrepository.ClientRepository
|
|
userRepository repository.UserRepository
|
|
roleRepository rolerepository.RoleRepository
|
|
warehouserepository warehouserepository.WarehouseRepository
|
|
refreshTokenRepository authRepo.RefreshTokenRepository
|
|
jwtService authService.JWTService
|
|
db *gorm.DB
|
|
}
|
|
|
|
// BulkCreate implements UserService.
|
|
func (s *userService) BulkCreate(ctx context.Context, req dto.BulkCreateUserRequest) error {
|
|
users := make([]entities.M_User, len(req.Users))
|
|
|
|
for i, r := range req.Users {
|
|
clientName := strings.ToLower(strings.TrimSpace(r.ClientName))
|
|
client, err := s.clientRepository.GetByName(ctx, s.db, clientName)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
hashedPassword, err := utils.HashPassword(r.Password)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
users[i] = entities.M_User{
|
|
Username: r.Username,
|
|
Email: r.Email,
|
|
Password: hashedPassword,
|
|
Name: r.Name,
|
|
Gender: r.Gender,
|
|
Address: r.Address,
|
|
Phone: r.Phone,
|
|
PhotoUrl: r.PhotoUrl,
|
|
ClientID: client.ID,
|
|
// MaintenanceGroupUserID: r.MaintenanceGroupUserID,
|
|
// LocationID: r.LocationID,
|
|
}
|
|
}
|
|
|
|
tx := s.db.Begin()
|
|
defer func() {
|
|
if r := recover(); r != nil {
|
|
tx.Rollback()
|
|
}
|
|
}()
|
|
|
|
err := s.userRepository.BulkCreate(ctx, tx, users)
|
|
if err != nil {
|
|
tx.Rollback()
|
|
return err
|
|
}
|
|
if err := tx.Commit().Error; err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// GetUserWarehouses implements UserService.
|
|
func (s *userService) GetUserWarehouses(ctx context.Context, userId string) ([]dto.UserResponse, error) {
|
|
user, err := s.userRepository.GetUserById(ctx, s.db, userId)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
var warehouses []pkgdto.IdNameResponse
|
|
for _, uw := range user.Warehouses {
|
|
warehouses = append(warehouses, pkgdto.IdNameResponse{
|
|
ID: uw.ID.String(),
|
|
Name: uw.Name,
|
|
})
|
|
}
|
|
|
|
response := dto.UserResponse{
|
|
ID: user.ID.String(),
|
|
Name: user.Name,
|
|
Warehouses: warehouses,
|
|
}
|
|
|
|
return []dto.UserResponse{response}, nil
|
|
}
|
|
|
|
// // AssignWarehouseToUser implements UserService.
|
|
// func (s *userService) AssignWarehouseToUser(ctx context.Context, userId string, warehouseIds []string) error {
|
|
// // Validasi userId
|
|
// if _, err := uuid.Parse(userId); err != nil {
|
|
// return errors.New("invalid userId format")
|
|
// }
|
|
|
|
// // Validasi warehouseIds
|
|
// for _, wid := range warehouseIds {
|
|
// if _, err := uuid.Parse(wid); err != nil {
|
|
// return errors.New("invalid warehouseId format: " + wid)
|
|
// }
|
|
// }
|
|
|
|
// // Hapus semua relasi warehouse lama user, lalu assign yang baru (replace)
|
|
// _, err := s.userRepository.AssignWarehousesToUser(ctx, s.db, userId, warehouseIds)
|
|
// if err != nil {
|
|
// return err
|
|
// }
|
|
// return nil
|
|
// }
|
|
|
|
// // RemoveWarehouseFromUser implements UserService.
|
|
// func (s *userService) RemoveWarehouseFromUser(ctx context.Context, userId string, warehouseIds []string) error {
|
|
// // Validasi userId
|
|
// if _, err := uuid.Parse(userId); err != nil {
|
|
// return errors.New("invalid userId format")
|
|
// }
|
|
|
|
// // Validasi warehouseIds
|
|
// for _, wid := range warehouseIds {
|
|
// if _, err := uuid.Parse(wid); err != nil {
|
|
// return errors.New("invalid warehouseId format: " + wid)
|
|
// }
|
|
// }
|
|
|
|
// _, err := s.userRepository.RemoveWarehousesFromUser(ctx, s.db, userId, warehouseIds)
|
|
// if err != nil {
|
|
// return err
|
|
// }
|
|
// return nil
|
|
// }
|
|
|
|
// SwitchWarehouse implements UserService.
|
|
func (s *userService) SwitchWarehouse(ctx context.Context, userId string, req dto.SwitchWarehouseRequest) (authDto.TokenResponse, error) {
|
|
user, err := s.userRepository.GetUserById(ctx, s.db, userId)
|
|
if err != nil {
|
|
return authDto.TokenResponse{}, err
|
|
}
|
|
|
|
// Delete old refresh tokens for user
|
|
err = s.refreshTokenRepository.DeleteByUserID(ctx, s.db, user.ID.String())
|
|
if err != nil {
|
|
return authDto.TokenResponse{}, err
|
|
}
|
|
|
|
// Get first role and warehouse for token generation
|
|
if len(user.Roles) == 0 {
|
|
return authDto.TokenResponse{}, errors.New("user has no roles assigned")
|
|
}
|
|
if len(user.Warehouses) == 0 {
|
|
return authDto.TokenResponse{}, errors.New("user has no warehouses assigned")
|
|
}
|
|
|
|
role, err := s.roleRepository.GetRoleByID(ctx, s.db, req.ActiveRoleID)
|
|
if err != nil {
|
|
return authDto.TokenResponse{}, err
|
|
}
|
|
|
|
warehouse, err := s.warehouserepository.GetById(ctx, s.db, req.WarehouseID)
|
|
if err != nil {
|
|
return authDto.TokenResponse{}, err
|
|
}
|
|
|
|
accessToken := s.jwtService.GenerateAccessToken(
|
|
user.ClientID.String(),
|
|
userId,
|
|
role.ID.String(), // gunakan role yang sedang aktif
|
|
warehouse.ID.String(), // warehouse yang dipilih
|
|
)
|
|
refreshTokenString, expiresAt := s.jwtService.GenerateRefreshToken()
|
|
|
|
refreshToken := entities.RefreshToken{
|
|
ID: uuid.New(),
|
|
UserID: user.ID,
|
|
ClientID: user.ClientID,
|
|
Token: refreshTokenString,
|
|
ExpiresAt: expiresAt,
|
|
}
|
|
|
|
_, err = s.refreshTokenRepository.Create(ctx, s.db, refreshToken)
|
|
if err != nil {
|
|
return authDto.TokenResponse{}, err
|
|
}
|
|
|
|
return authDto.TokenResponse{
|
|
AccessToken: accessToken,
|
|
RefreshToken: refreshTokenString,
|
|
}, nil
|
|
}
|
|
|
|
func (s *userService) AssignWarehouse(ctx context.Context, userId string, warehouseId string) error {
|
|
return s.userRepository.AddUserWarehouse(ctx, s.db, userId, warehouseId)
|
|
}
|
|
|
|
func (s *userService) RemoveWarehouse(ctx context.Context, userId string, warehouseId string) error {
|
|
return s.userRepository.RemoveUserWarehouse(ctx, s.db, userId, warehouseId)
|
|
}
|
|
|
|
func (s *userService) AssignWarehousesReplace(ctx context.Context, userId string, warehouseIds []string) error {
|
|
|
|
// Validasi input
|
|
if _, err := uuid.Parse(userId); err != nil {
|
|
return errors.New("invalid userId format")
|
|
}
|
|
|
|
for _, wid := range warehouseIds {
|
|
if _, err := uuid.Parse(wid); err != nil {
|
|
return fmt.Errorf("invalid warehouseId format: %s", wid)
|
|
}
|
|
}
|
|
|
|
// Mulai transaksi
|
|
tx := s.db.Begin()
|
|
|
|
// Hapus relasi lama
|
|
if err := s.userRepository.ClearUserWarehouses(ctx, tx, userId); err != nil {
|
|
tx.Rollback()
|
|
return err
|
|
}
|
|
|
|
// Tambahkan relasi baru
|
|
if err := s.userRepository.AddUserWarehouses(ctx, tx, userId, warehouseIds); err != nil {
|
|
tx.Rollback()
|
|
return err
|
|
}
|
|
|
|
return tx.Commit().Error
|
|
}
|
|
|
|
// GetAll implements UserService.
|
|
func (s *userService) GetAll(ctx context.Context) ([]dto.UserResponse, error) {
|
|
users, err := s.userRepository.GetAll(ctx, s.db)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
var responses []dto.UserResponse
|
|
for _, user := range users {
|
|
var roles []dto.UserRolesResponse
|
|
for _, role := range user.Roles {
|
|
roles = append(roles, dto.UserRolesResponse{
|
|
ID: role.ID.String(),
|
|
Name: role.Name,
|
|
})
|
|
}
|
|
|
|
client := pkgdto.IdNameResponse{}
|
|
if user.Client.ID != uuid.Nil {
|
|
client.ID = user.Client.ID.String()
|
|
client.Name = user.Client.Name
|
|
}
|
|
|
|
responses = append(responses, dto.UserResponse{
|
|
ID: user.ID.String(),
|
|
Name: user.Name,
|
|
Username: user.Username,
|
|
Email: user.Email,
|
|
Gender: user.Gender,
|
|
Address: user.Address,
|
|
Phone: user.Phone,
|
|
PhotoUrl: user.PhotoUrl,
|
|
Roles: roles,
|
|
Client: client,
|
|
})
|
|
}
|
|
|
|
return responses, nil
|
|
}
|
|
|
|
// Create implements UserService.
|
|
// Create implements UserService.
|
|
func (s *userService) Create(ctx context.Context, req dto.UserCreateRequest) (dto.UserResponse, error) {
|
|
// Cek apakah email sudah terdaftar
|
|
// _, exists, err := s.userRepository.CheckEmail(ctx, s.db, req.Email)
|
|
// if err != nil && err != gorm.ErrRecordNotFound {
|
|
// return dto.UserResponse{}, err
|
|
// }
|
|
// if exists {
|
|
// return dto.UserResponse{}, dto.ErrEmailAlreadyExists
|
|
// }
|
|
|
|
// Hash password
|
|
hashedPassword, err := utils.HashPassword(req.Password)
|
|
if err != nil {
|
|
return dto.UserResponse{}, err
|
|
}
|
|
|
|
user := entities.M_User{
|
|
Name: req.Name,
|
|
Username: req.Username,
|
|
Email: req.Email,
|
|
Password: hashedPassword,
|
|
Gender: req.Gender,
|
|
Address: req.Address,
|
|
Phone: req.Phone,
|
|
PhotoUrl: req.PhotoUrl,
|
|
ClientID: req.ClientID,
|
|
MaintenanceGroupUserID: req.MaintenanceGroupUserID,
|
|
LocationID: req.LocationID,
|
|
}
|
|
|
|
createdUser, err := s.userRepository.Register(ctx, s.db, user)
|
|
if err != nil {
|
|
return dto.UserResponse{}, err
|
|
}
|
|
|
|
return dto.UserResponse{
|
|
ID: createdUser.ID.String(),
|
|
Name: createdUser.Name,
|
|
Username: createdUser.Username,
|
|
Email: createdUser.Email,
|
|
Phone: createdUser.Phone,
|
|
Gender: createdUser.Gender,
|
|
Address: createdUser.Address,
|
|
PhotoUrl: createdUser.PhotoUrl,
|
|
}, nil
|
|
}
|
|
|
|
func NewUserService(
|
|
userRepo repository.UserRepository,
|
|
roleRepo rolerepository.RoleRepository,
|
|
warehouserepository warehouserepository.WarehouseRepository,
|
|
clientRepository clientrepository.ClientRepository,
|
|
refreshTokenRepo authRepo.RefreshTokenRepository,
|
|
jwtService authService.JWTService,
|
|
db *gorm.DB,
|
|
) UserService {
|
|
return &userService{
|
|
userRepository: userRepo,
|
|
roleRepository: roleRepo,
|
|
warehouserepository: warehouserepository,
|
|
clientRepository: clientRepository,
|
|
refreshTokenRepository: refreshTokenRepo,
|
|
jwtService: jwtService,
|
|
db: db,
|
|
}
|
|
}
|
|
|
|
// SwitchRole implements UserService.
|
|
func (s *userService) SwitchRole(ctx context.Context, userId string, req dto.SwitchRoleRequest) (authDto.TokenResponse, error) {
|
|
// Switch user role in repository
|
|
user, err := s.userRepository.GetUserById(ctx, s.db, userId)
|
|
if err != nil {
|
|
return authDto.TokenResponse{}, err
|
|
}
|
|
|
|
// Delete old refresh tokens for user
|
|
err = s.refreshTokenRepository.DeleteByUserID(ctx, s.db, user.ID.String())
|
|
if err != nil {
|
|
return authDto.TokenResponse{}, err
|
|
}
|
|
|
|
// Get first role and warehouse for token generation
|
|
if len(user.Roles) == 0 {
|
|
return authDto.TokenResponse{}, errors.New("user has no roles assigned")
|
|
}
|
|
if len(user.Warehouses) == 0 {
|
|
return authDto.TokenResponse{}, errors.New("user has no warehouses assigned")
|
|
}
|
|
role, err := s.roleRepository.GetRoleByID(ctx, s.db, req.RoleID)
|
|
if err != nil {
|
|
return authDto.TokenResponse{}, err
|
|
}
|
|
warehouse, err := s.warehouserepository.GetById(ctx, s.db, req.ActiveWarehouseID)
|
|
if err != nil {
|
|
return authDto.TokenResponse{}, err
|
|
}
|
|
|
|
accessToken := s.jwtService.GenerateAccessToken(
|
|
user.ClientID.String(),
|
|
userId,
|
|
role.ID.String(), // gunakan role yang sedang aktif
|
|
warehouse.ID.String(), // warehouse yang dipilih
|
|
)
|
|
refreshTokenString, expiresAt := s.jwtService.GenerateRefreshToken()
|
|
|
|
refreshToken := entities.RefreshToken{
|
|
ID: uuid.New(),
|
|
UserID: user.ID,
|
|
ClientID: user.ClientID,
|
|
Token: refreshTokenString,
|
|
ExpiresAt: expiresAt,
|
|
}
|
|
|
|
_, err = s.refreshTokenRepository.Create(ctx, s.db, refreshToken)
|
|
if err != nil {
|
|
return authDto.TokenResponse{}, err
|
|
}
|
|
|
|
return authDto.TokenResponse{
|
|
AccessToken: accessToken,
|
|
RefreshToken: refreshTokenString,
|
|
}, nil
|
|
}
|
|
|
|
func (s *userService) Register(ctx context.Context, req dto.UserCreateRequest) (dto.UserResponse, error) {
|
|
_, exists, err := s.userRepository.CheckEmail(ctx, s.db, req.Email)
|
|
if err != nil && err != gorm.ErrRecordNotFound {
|
|
return dto.UserResponse{}, err
|
|
}
|
|
if exists {
|
|
return dto.UserResponse{}, dto.ErrEmailAlreadyExists
|
|
}
|
|
|
|
enryptPassword, err := utils.HashPassword(req.Password)
|
|
if err != nil {
|
|
return dto.UserResponse{}, err
|
|
}
|
|
|
|
user := entities.M_User{
|
|
Name: req.Name,
|
|
Username: req.Username,
|
|
Email: req.Email,
|
|
Password: enryptPassword,
|
|
Gender: req.Gender,
|
|
Address: req.Address,
|
|
Phone: req.Phone,
|
|
PhotoUrl: req.PhotoUrl,
|
|
ClientID: req.ClientID,
|
|
}
|
|
|
|
createdUser, err := s.userRepository.Register(ctx, s.db, user)
|
|
if err != nil {
|
|
return dto.UserResponse{}, err
|
|
}
|
|
return dto.UserResponse{
|
|
ID: createdUser.ID.String(),
|
|
Name: createdUser.Name,
|
|
Username: createdUser.Username,
|
|
Email: createdUser.Email,
|
|
Phone: createdUser.Phone,
|
|
Gender: createdUser.Gender,
|
|
Address: createdUser.Address,
|
|
PhotoUrl: createdUser.PhotoUrl,
|
|
}, nil
|
|
}
|
|
|
|
func (s *userService) GetUserById(ctx context.Context, userId string) (dto.UserResponse, error) {
|
|
user, err := s.userRepository.GetUserById(ctx, s.db, userId)
|
|
if err != nil {
|
|
return dto.UserResponse{}, err
|
|
}
|
|
|
|
var roles []dto.UserRolesResponse
|
|
for _, ur := range user.Roles {
|
|
roles = append(roles, dto.UserRolesResponse{
|
|
ID: ur.ID.String(),
|
|
Name: ur.Name,
|
|
})
|
|
}
|
|
|
|
var client pkgdto.IdNameResponse
|
|
client = pkgdto.IdNameResponse{
|
|
ID: user.Client.ID.String(),
|
|
Name: user.Client.Name,
|
|
}
|
|
|
|
var warehouses []pkgdto.IdNameResponse
|
|
for _, uw := range user.Warehouses {
|
|
warehouses = append(warehouses, pkgdto.IdNameResponse{
|
|
ID: uw.ID.String(),
|
|
Name: uw.Name,
|
|
})
|
|
}
|
|
|
|
return dto.UserResponse{
|
|
ID: user.ID.String(),
|
|
Name: user.Name,
|
|
Username: user.Username,
|
|
Email: user.Email,
|
|
Gender: user.Gender,
|
|
Address: user.Address,
|
|
Phone: user.Phone,
|
|
PhotoUrl: user.PhotoUrl,
|
|
Roles: roles,
|
|
Client: client,
|
|
Warehouses: warehouses,
|
|
}, nil
|
|
}
|
|
|
|
func (s *userService) Verify(ctx context.Context, req dto.UserLoginRequest) (authDto.TokenResponse, error) {
|
|
var user entities.M_User
|
|
var err error
|
|
|
|
if strings.Contains(req.Login, "@") {
|
|
user, err = s.userRepository.GetUserByEmail(ctx, s.db, req.Login)
|
|
} else {
|
|
user, err = s.userRepository.GetUserByUsername(ctx, s.db, req.Login)
|
|
}
|
|
|
|
if err != nil {
|
|
return authDto.TokenResponse{}, dto.ErrUserNotFound
|
|
}
|
|
|
|
isValid := utils.CheckPasswordHash(req.Password, user.Password)
|
|
if !isValid {
|
|
return authDto.TokenResponse{}, dto.ErrUserNotFound
|
|
}
|
|
roles := append([]entities.M_Role{}, user.Roles...)
|
|
if len(roles) == 0 {
|
|
return authDto.TokenResponse{}, errors.New("user has no roles assigned")
|
|
}
|
|
|
|
warehouses := append([]entities.MWarehouseEntity{}, user.Warehouses...)
|
|
warehouseID := ""
|
|
if user.Username == pkgconstants.SUPERADMIN {
|
|
warehouseID = ""
|
|
} else if len(warehouses) > 0 {
|
|
warehouseID = warehouses[0].ID.String()
|
|
} else {
|
|
return authDto.TokenResponse{}, errors.New("user has no warehouses assigned")
|
|
}
|
|
|
|
// DeleteByUserID
|
|
err = s.refreshTokenRepository.DeleteByUserID(ctx, s.db, user.ID.String())
|
|
if err != nil {
|
|
return authDto.TokenResponse{}, err
|
|
}
|
|
|
|
accessToken := s.jwtService.GenerateAccessToken(user.ClientID.String(), user.ID.String(), roles[0].ID.String(), warehouseID)
|
|
refreshTokenString, expiresAt := s.jwtService.GenerateRefreshToken()
|
|
|
|
refreshToken := entities.RefreshToken{
|
|
ID: uuid.New(),
|
|
UserID: user.ID,
|
|
ClientID: user.ClientID,
|
|
Token: refreshTokenString,
|
|
ExpiresAt: expiresAt,
|
|
}
|
|
|
|
_, err = s.refreshTokenRepository.Create(ctx, s.db, refreshToken)
|
|
if err != nil {
|
|
return authDto.TokenResponse{}, err
|
|
}
|
|
|
|
return authDto.TokenResponse{
|
|
AccessToken: accessToken,
|
|
RefreshToken: refreshTokenString,
|
|
}, nil
|
|
}
|
|
|
|
func (s *userService) SendVerificationEmail(ctx context.Context, req dto.SendVerificationEmailRequest) error {
|
|
user, err := s.userRepository.GetUserByEmail(ctx, s.db, req.Email)
|
|
if err != nil {
|
|
return dto.ErrEmailNotFound
|
|
}
|
|
|
|
// if user.IsVerified {
|
|
// return dto.ErrAccountAlreadyVerified
|
|
// }
|
|
|
|
roles := append([]entities.M_Role{}, user.Roles...)
|
|
if len(roles) == 0 {
|
|
return errors.New("user has no roles assigned")
|
|
}
|
|
|
|
warehouses := append([]entities.MWarehouseEntity{}, user.Warehouses...)
|
|
if len(warehouses) == 0 {
|
|
return errors.New("user has no warehouses assigned")
|
|
}
|
|
|
|
verificationToken := s.jwtService.GenerateAccessToken(user.ClientID.String(), user.ID.String(), roles[0].ID.String(), warehouses[0].ID.String())
|
|
|
|
subject := "Email Verification"
|
|
body := "Please verify your email using this token: " + verificationToken
|
|
|
|
return utils.SendMail(user.Email, subject, body)
|
|
}
|
|
|
|
func (s *userService) VerifyEmail(ctx context.Context, req dto.VerifyEmailRequest) (dto.VerifyEmailResponse, error) {
|
|
token, err := s.jwtService.ValidateToken(req.Token)
|
|
if err != nil || !token.Valid {
|
|
return dto.VerifyEmailResponse{}, dto.ErrTokenInvalid
|
|
}
|
|
|
|
userTokenInfo, err := s.jwtService.GetUserIDByToken(req.Token)
|
|
if err != nil {
|
|
return dto.VerifyEmailResponse{}, dto.ErrTokenInvalid
|
|
}
|
|
|
|
user, err := s.userRepository.GetUserById(ctx, s.db, userTokenInfo.UserID)
|
|
if err != nil {
|
|
return dto.VerifyEmailResponse{}, dto.ErrUserNotFound
|
|
}
|
|
|
|
// user.IsVerified = true
|
|
updatedUser, err := s.userRepository.Update(ctx, s.db, user)
|
|
if err != nil {
|
|
return dto.VerifyEmailResponse{}, err
|
|
}
|
|
|
|
return dto.VerifyEmailResponse{
|
|
Email: updatedUser.Email,
|
|
// IsVerified: updatedUser.IsVerified,
|
|
}, nil
|
|
}
|
|
|
|
func (s *userService) Update(ctx context.Context, req dto.UserUpdateRequest, userId string) (dto.UserUpdateResponse, error) {
|
|
user, err := s.userRepository.GetUserById(ctx, s.db, userId)
|
|
if err != nil {
|
|
return dto.UserUpdateResponse{}, dto.ErrUserNotFound
|
|
}
|
|
|
|
if req.Name != "" {
|
|
user.Name = req.Name
|
|
}
|
|
if req.Email != "" {
|
|
user.Email = req.Email
|
|
}
|
|
if req.Username != "" {
|
|
user.Username = req.Username
|
|
}
|
|
if req.Password != "" {
|
|
enryptPassword, err := utils.HashPassword(req.Password)
|
|
if err != nil {
|
|
return dto.UserUpdateResponse{}, err
|
|
}
|
|
user.Password = enryptPassword
|
|
}
|
|
if req.Gender != "" {
|
|
user.Gender = req.Gender
|
|
}
|
|
if req.Address != "" {
|
|
user.Address = req.Address
|
|
}
|
|
if req.Phone != "" {
|
|
user.Phone = req.Phone
|
|
}
|
|
if req.PhotoUrl != "" {
|
|
user.PhotoUrl = req.PhotoUrl
|
|
}
|
|
if req.ClientID != uuid.Nil {
|
|
user.ClientID = req.ClientID
|
|
}
|
|
if req.MaintenanceGroupUserID != uuid.Nil {
|
|
user.MaintenanceGroupUserID = req.MaintenanceGroupUserID
|
|
}
|
|
if req.LocationID != uuid.Nil {
|
|
user.LocationID = req.LocationID
|
|
}
|
|
|
|
updatedUser, err := s.userRepository.Update(ctx, s.db, user)
|
|
if err != nil {
|
|
return dto.UserUpdateResponse{}, err
|
|
}
|
|
|
|
return dto.UserUpdateResponse{
|
|
ID: updatedUser.ID.String(),
|
|
Name: updatedUser.Name,
|
|
Username: updatedUser.Username,
|
|
Phone: updatedUser.Phone,
|
|
Email: updatedUser.Email,
|
|
Gender: updatedUser.Gender,
|
|
Address: updatedUser.Address,
|
|
PhotoUrl: updatedUser.PhotoUrl,
|
|
}, nil
|
|
}
|
|
|
|
func (s *userService) Delete(ctx context.Context, userId string) error {
|
|
return s.userRepository.Delete(ctx, s.db, userId)
|
|
}
|
|
|
|
func (s *userService) RefreshToken(ctx context.Context, req authDto.RefreshTokenRequest) (authDto.TokenResponse, error) {
|
|
refreshToken, err := s.refreshTokenRepository.FindByToken(ctx, s.db, req.RefreshToken)
|
|
if err != nil {
|
|
return authDto.TokenResponse{}, err
|
|
}
|
|
roles := append([]entities.M_Role{}, refreshToken.User.Roles...)
|
|
if len(roles) == 0 {
|
|
return authDto.TokenResponse{}, errors.New("user has no roles assigned")
|
|
}
|
|
warehouses := append([]entities.MWarehouseEntity{}, refreshToken.User.Warehouses...)
|
|
if len(warehouses) == 0 {
|
|
return authDto.TokenResponse{}, errors.New("user has no warehouses assigned")
|
|
}
|
|
|
|
accessToken := s.jwtService.GenerateAccessToken(refreshToken.ClientID.String(), refreshToken.UserID.String(), roles[0].ID.String(), warehouses[0].ID.String())
|
|
// newRefreshTokenString, expiresAt := s.jwtService.GenerateRefreshToken()
|
|
|
|
// err = s.refreshTokenRepository.DeleteByToken(ctx, s.db, req.RefreshToken)
|
|
// if err != nil {
|
|
// return authDto.TokenResponse{}, err
|
|
// }
|
|
|
|
// newRefreshToken := entities.RefreshToken{
|
|
// ID: uuid.New(),
|
|
// UserID: refreshToken.UserID,
|
|
// ClientID: refreshToken.ClientID,
|
|
// Token: newRefreshTokenString,
|
|
// ExpiresAt: expiresAt,
|
|
// }
|
|
|
|
// _, err = s.refreshTokenRepository.Create(ctx, s.db, newRefreshToken)
|
|
// if err != nil {
|
|
// return authDto.TokenResponse{}, err
|
|
// }
|
|
|
|
return authDto.TokenResponse{
|
|
AccessToken: accessToken,
|
|
// RefreshToken: newRefreshTokenString,
|
|
RefreshToken: req.RefreshToken, // atau kosongkan jika tidak ingin return refresh token sama sekali
|
|
|
|
}, nil
|
|
}
|