91 lines
2.3 KiB
Go
91 lines
2.3 KiB
Go
|
package services
|
||
|
|
||
|
import (
|
||
|
"errors"
|
||
|
"studioj/boilerplate_go/internal/models"
|
||
|
"studioj/boilerplate_go/internal/repositories"
|
||
|
"time"
|
||
|
|
||
|
"github.com/google/uuid"
|
||
|
"golang.org/x/crypto/bcrypt"
|
||
|
)
|
||
|
|
||
|
type authService struct {
|
||
|
userRepository repositories.UserRepository
|
||
|
tokenRepository repositories.TokenRepository
|
||
|
}
|
||
|
|
||
|
type AuthService interface {
|
||
|
Register(*models.RegisterRequest) (*models.User, error)
|
||
|
Login(*models.LoginRequest) (*models.User, error)
|
||
|
CreateToken(string) (*models.Token, error)
|
||
|
}
|
||
|
|
||
|
func NewAuthService(userRepository repositories.UserRepository, tokenRepository repositories.TokenRepository) AuthService {
|
||
|
return &authService{
|
||
|
userRepository: userRepository,
|
||
|
tokenRepository: tokenRepository,
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (s *authService) Register(request *models.RegisterRequest) (*models.User, error) {
|
||
|
hash, err := bcrypt.GenerateFromPassword([]byte(request.Password), 10)
|
||
|
if err != nil {
|
||
|
return nil, errors.New("fail to hash password")
|
||
|
}
|
||
|
|
||
|
// Create the user
|
||
|
newUser := models.User{
|
||
|
ID: uuid.NewString(),
|
||
|
Username: request.Username,
|
||
|
Password: string(hash),
|
||
|
}
|
||
|
|
||
|
user, err := s.userRepository.Create(&newUser)
|
||
|
if err != nil {
|
||
|
return nil, errors.New("fail to create user")
|
||
|
}
|
||
|
|
||
|
return user, err
|
||
|
}
|
||
|
|
||
|
func (s *authService) Login(request *models.LoginRequest) (*models.User, error) {
|
||
|
user, err := s.userRepository.FindByUsername(request.Username)
|
||
|
if err != nil || user == nil {
|
||
|
return nil, errors.New("invalid user or password")
|
||
|
}
|
||
|
|
||
|
err = bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(request.Password))
|
||
|
if err != nil {
|
||
|
return nil, errors.New("invalid user or password")
|
||
|
}
|
||
|
return user, nil
|
||
|
}
|
||
|
|
||
|
func (s *authService) CreateToken(user_id string) (*models.Token, error) {
|
||
|
tokenExpiredAt := time.Now().Add(time.Hour * 24 * 30)
|
||
|
accessToken, err := s.tokenRepository.Generate(user_id, tokenExpiredAt.Unix())
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
|
||
|
refreshExpiredAt := time.Now().Add(time.Hour * 24 * 90)
|
||
|
refreshToken, err := s.tokenRepository.Generate(user_id, refreshExpiredAt.Unix())
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
|
||
|
newToken := &models.Token{
|
||
|
ID: uuid.NewString(),
|
||
|
UserID: user_id,
|
||
|
Token: accessToken,
|
||
|
RefreshToken: refreshToken,
|
||
|
Status: "valid",
|
||
|
ExpireAt: tokenExpiredAt,
|
||
|
}
|
||
|
|
||
|
token, err := s.tokenRepository.Create(newToken)
|
||
|
|
||
|
return token, err
|
||
|
}
|