feat(user): Add username support for login and implement username checks in repository
This commit is contained in:
parent
62a188fcc6
commit
98bdfce83a
|
|
@ -53,7 +53,7 @@ func (r *refreshTokenRepository) FindByToken(ctx context.Context, tx *gorm.DB, t
|
|||
var refreshToken entities.RefreshToken
|
||||
if err := tx.WithContext(ctx).
|
||||
Preload("User").
|
||||
Preload("User.UserRoles.Role").
|
||||
Preload("User.Roles").
|
||||
Take(&refreshToken).Error; err != nil {
|
||||
return entities.RefreshToken{}, err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -130,7 +130,7 @@ type (
|
|||
}
|
||||
|
||||
UserLoginRequest struct {
|
||||
Email string `json:"email" form:"email" binding:"required"`
|
||||
Login string `json:"login" form:"login" binding:"required"`
|
||||
Password string `json:"password" form:"password" binding:"required"`
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,9 @@ type (
|
|||
Register(ctx context.Context, tx *gorm.DB, user entities.M_User) (entities.M_User, error)
|
||||
GetUserById(ctx context.Context, tx *gorm.DB, userId string) (entities.M_User, error)
|
||||
GetUserByEmail(ctx context.Context, tx *gorm.DB, email string) (entities.M_User, error)
|
||||
GetUserByUsername(ctx context.Context, tx *gorm.DB, username string) (entities.M_User, error)
|
||||
CheckEmail(ctx context.Context, tx *gorm.DB, email string) (entities.M_User, bool, error)
|
||||
CheckUsername(ctx context.Context, tx *gorm.DB, username string) (entities.M_User, bool, error)
|
||||
Update(ctx context.Context, tx *gorm.DB, user entities.M_User) (entities.M_User, error)
|
||||
Delete(ctx context.Context, tx *gorm.DB, userId string) error
|
||||
SwitchRole(ctx context.Context, tx *gorm.DB, userId string, roleId string) (entities.M_User, error)
|
||||
|
|
@ -23,6 +25,37 @@ type (
|
|||
}
|
||||
)
|
||||
|
||||
// CheckUsername implements UserRepository.
|
||||
func (r *userRepository) CheckUsername(ctx context.Context, tx *gorm.DB, username string) (entities.M_User, bool, error) {
|
||||
if tx == nil {
|
||||
tx = r.db
|
||||
}
|
||||
|
||||
var user entities.M_User
|
||||
if err := tx.WithContext(ctx).Where("username = ?", username).Take(&user).Error; err != nil {
|
||||
return entities.M_User{}, false, err
|
||||
}
|
||||
|
||||
return user, true, nil
|
||||
}
|
||||
|
||||
// GetUserByUsername implements UserRepository.
|
||||
func (r *userRepository) GetUserByUsername(ctx context.Context, tx *gorm.DB, username string) (entities.M_User, error) {
|
||||
if tx == nil {
|
||||
tx = r.db
|
||||
}
|
||||
|
||||
var user entities.M_User
|
||||
if err := tx.WithContext(ctx).
|
||||
Preload("Roles").
|
||||
Where("username = ?", username).
|
||||
Take(&user).Error; err != nil {
|
||||
return entities.M_User{}, err
|
||||
}
|
||||
|
||||
return user, nil
|
||||
}
|
||||
|
||||
func NewUserRepository(db *gorm.DB) UserRepository {
|
||||
return &userRepository{
|
||||
db: db,
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ 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"
|
||||
|
|
@ -124,9 +125,17 @@ func (s *userService) GetUserById(ctx context.Context, userId string) (dto.UserR
|
|||
}
|
||||
|
||||
func (s *userService) Verify(ctx context.Context, req dto.UserLoginRequest) (authDto.TokenResponse, error) {
|
||||
user, err := s.userRepository.GetUserByEmail(ctx, s.db, req.Email)
|
||||
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.ErrEmailNotFound
|
||||
return authDto.TokenResponse{}, dto.ErrUserNotFound
|
||||
}
|
||||
|
||||
isValid := utils.CheckPasswordHash(req.Password, user.Password)
|
||||
|
|
@ -134,19 +143,18 @@ func (s *userService) Verify(ctx context.Context, req dto.UserLoginRequest) (aut
|
|||
fmt.Println("Password validation error:", err)
|
||||
return authDto.TokenResponse{}, dto.ErrUserNotFound
|
||||
}
|
||||
// Ambil roles dari UserRoles
|
||||
roles := append([]entities.M_Role{}, user.Roles...)
|
||||
// var roles []dto.UserRolesResponse
|
||||
// for _, ur := range user.Roles {
|
||||
// roles = append(roles, dto.UserRolesResponse{
|
||||
// ID: ur.ID.String(),
|
||||
// Name: ur.Name,
|
||||
// })
|
||||
// }
|
||||
|
||||
if len(roles) == 0 {
|
||||
return authDto.TokenResponse{}, errors.New("user has no roles 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())
|
||||
refreshTokenString, expiresAt := s.jwtService.GenerateRefreshToken()
|
||||
|
||||
|
|
@ -292,31 +300,34 @@ func (s *userService) RefreshToken(ctx context.Context, req authDto.RefreshToken
|
|||
}
|
||||
roles := append([]entities.M_Role{}, refreshToken.User.Roles...)
|
||||
if len(roles) == 0 {
|
||||
return authDto.TokenResponse{}, errors.New("user has no roles assigned")
|
||||
return authDto.TokenResponse{}, errors.New("1 user has no roles assigned")
|
||||
}
|
||||
|
||||
accessToken := s.jwtService.GenerateAccessToken(refreshToken.ClientID.String(), refreshToken.UserID.String(), roles[0].ID.String())
|
||||
newRefreshTokenString, expiresAt := s.jwtService.GenerateRefreshToken()
|
||||
// newRefreshTokenString, expiresAt := s.jwtService.GenerateRefreshToken()
|
||||
|
||||
err = s.refreshTokenRepository.DeleteByToken(ctx, s.db, req.RefreshToken)
|
||||
if err != nil {
|
||||
return authDto.TokenResponse{}, err
|
||||
}
|
||||
// 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,
|
||||
Token: newRefreshTokenString,
|
||||
ExpiresAt: expiresAt,
|
||||
}
|
||||
// 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
|
||||
}
|
||||
// _, err = s.refreshTokenRepository.Create(ctx, s.db, newRefreshToken)
|
||||
// if err != nil {
|
||||
// return authDto.TokenResponse{}, err
|
||||
// }
|
||||
|
||||
return authDto.TokenResponse{
|
||||
AccessToken: accessToken,
|
||||
RefreshToken: newRefreshTokenString,
|
||||
AccessToken: accessToken,
|
||||
// RefreshToken: newRefreshTokenString,
|
||||
RefreshToken: req.RefreshToken, // atau kosongkan jika tidak ingin return refresh token sama sekali
|
||||
|
||||
}, nil
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue