MIF_E31222379_BE/internal/services/userpin_service.go

118 lines
3.2 KiB
Go

package services
import (
"fmt"
"time"
"github.com/pahmiudahgede/senggoldong/dto"
"github.com/pahmiudahgede/senggoldong/internal/repositories"
"github.com/pahmiudahgede/senggoldong/model"
"github.com/pahmiudahgede/senggoldong/utils"
"golang.org/x/crypto/bcrypt"
)
type UserPinService interface {
CreateUserPin(userID, pin string) (*dto.UserPinResponseDTO, error)
VerifyUserPin(userID, pin string) (*dto.UserPinResponseDTO, error)
CheckPinStatus(userID string) (string, *dto.UserPinResponseDTO, error)
}
type userPinService struct {
UserPinRepo repositories.UserPinRepository
}
func NewUserPinService(userPinRepo repositories.UserPinRepository) UserPinService {
return &userPinService{UserPinRepo: userPinRepo}
}
func (s *userPinService) VerifyUserPin(pin string, userID string) (*dto.UserPinResponseDTO, error) {
userPin, err := s.UserPinRepo.FindByUserID(userID)
if err != nil {
return nil, fmt.Errorf("user pin not found")
}
err = bcrypt.CompareHashAndPassword([]byte(userPin.Pin), []byte(pin))
if err != nil {
return nil, fmt.Errorf("incorrect pin")
}
createdAt, _ := utils.FormatDateToIndonesianFormat(userPin.CreatedAt)
updatedAt, _ := utils.FormatDateToIndonesianFormat(userPin.UpdatedAt)
userPinResponse := &dto.UserPinResponseDTO{
ID: userPin.ID,
UserID: userPin.UserID,
Pin: userPin.Pin,
CreatedAt: createdAt,
UpdatedAt: updatedAt,
}
return userPinResponse, nil
}
func (s *userPinService) CheckPinStatus(userID string) (string, *dto.UserPinResponseDTO, error) {
userPin, err := s.UserPinRepo.FindByUserID(userID)
if err != nil {
return "Pin not created", nil, nil
}
createdAt, _ := utils.FormatDateToIndonesianFormat(userPin.CreatedAt)
updatedAt, _ := utils.FormatDateToIndonesianFormat(userPin.UpdatedAt)
userPinResponse := &dto.UserPinResponseDTO{
ID: userPin.ID,
UserID: userPin.UserID,
Pin: userPin.Pin,
CreatedAt: createdAt,
UpdatedAt: updatedAt,
}
return "Pin already created", userPinResponse, nil
}
func (s *userPinService) CreateUserPin(userID, pin string) (*dto.UserPinResponseDTO, error) {
existingPin, err := s.UserPinRepo.FindByUserID(userID)
if err != nil && existingPin != nil {
return nil, fmt.Errorf("you have already created a pin, you don't need to create another one")
}
hashedPin, err := bcrypt.GenerateFromPassword([]byte(pin), bcrypt.DefaultCost)
if err != nil {
return nil, fmt.Errorf("error hashing the pin: %v", err)
}
newPin := model.UserPin{
UserID: userID,
Pin: string(hashedPin),
}
err = s.UserPinRepo.Create(&newPin)
if err != nil {
return nil, fmt.Errorf("error creating user pin: %v", err)
}
createdAt, _ := utils.FormatDateToIndonesianFormat(newPin.CreatedAt)
updatedAt, _ := utils.FormatDateToIndonesianFormat(newPin.UpdatedAt)
userPinResponse := &dto.UserPinResponseDTO{
ID: newPin.ID,
UserID: newPin.UserID,
Pin: newPin.Pin,
CreatedAt: createdAt,
UpdatedAt: updatedAt,
}
cacheKey := fmt.Sprintf("userpin:%s", userID)
cacheData := map[string]interface{}{
"data": userPinResponse,
}
err = utils.SetJSONData(cacheKey, cacheData, time.Hour*24)
if err != nil {
fmt.Printf("Error caching new user pin to Redis: %v\n", err)
}
return userPinResponse, nil
}