134 lines
3.4 KiB
Go
134 lines
3.4 KiB
Go
package services
|
|
|
|
import (
|
|
"fmt"
|
|
"time"
|
|
|
|
"rijig/internal/repositories"
|
|
"rijig/model"
|
|
"rijig/utils"
|
|
|
|
"golang.org/x/crypto/bcrypt"
|
|
)
|
|
|
|
type UserPinService interface {
|
|
CreateUserPin(userID, pin string) (string, error)
|
|
VerifyUserPin(userID, pin string) (string, error)
|
|
CheckPinStatus(userID string) (string, error)
|
|
UpdateUserPin(userID, oldPin, newPin string) (string, error)
|
|
}
|
|
|
|
type userPinService struct {
|
|
UserPinRepo repositories.UserPinRepository
|
|
}
|
|
|
|
func NewUserPinService(userPinRepo repositories.UserPinRepository) UserPinService {
|
|
return &userPinService{UserPinRepo: userPinRepo}
|
|
}
|
|
|
|
func (s *userPinService) VerifyUserPin(userID, pin string) (string, error) {
|
|
if pin == "" {
|
|
return "", fmt.Errorf("pin tidak boleh kosong")
|
|
}
|
|
|
|
userPin, err := s.UserPinRepo.FindByUserID(userID)
|
|
if err != nil {
|
|
return "", fmt.Errorf("error fetching user pin: %v", err)
|
|
}
|
|
if userPin == nil {
|
|
return "", fmt.Errorf("user pin not found")
|
|
}
|
|
|
|
err = bcrypt.CompareHashAndPassword([]byte(userPin.Pin), []byte(pin))
|
|
if err != nil {
|
|
return "", fmt.Errorf("incorrect pin")
|
|
}
|
|
|
|
return "Pin yang anda masukkan benar", nil
|
|
}
|
|
|
|
func (s *userPinService) CheckPinStatus(userID string) (string, error) {
|
|
userPin, err := s.UserPinRepo.FindByUserID(userID)
|
|
if err != nil {
|
|
return "", fmt.Errorf("error checking pin status: %v", err)
|
|
}
|
|
if userPin == nil {
|
|
return "Pin not created", nil
|
|
}
|
|
|
|
return "Pin already created", nil
|
|
}
|
|
|
|
func (s *userPinService) CreateUserPin(userID, pin string) (string, error) {
|
|
|
|
existingPin, err := s.UserPinRepo.FindByUserID(userID)
|
|
if err != nil {
|
|
return "", fmt.Errorf("error checking existing pin: %v", err)
|
|
}
|
|
|
|
if existingPin != nil {
|
|
return "", 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 "", 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 "", fmt.Errorf("error creating user pin: %v", err)
|
|
}
|
|
|
|
cacheKey := fmt.Sprintf("userpin:%s", userID)
|
|
cacheData := map[string]interface{}{"data": newPin}
|
|
err = utils.SetJSONData(cacheKey, cacheData, time.Hour*24)
|
|
if err != nil {
|
|
fmt.Printf("Error caching new user pin to Redis: %v\n", err)
|
|
}
|
|
|
|
return "Pin berhasil dibuat", nil
|
|
}
|
|
|
|
func (s *userPinService) UpdateUserPin(userID, oldPin, newPin string) (string, error) {
|
|
|
|
userPin, err := s.UserPinRepo.FindByUserID(userID)
|
|
if err != nil {
|
|
return "", fmt.Errorf("error fetching user pin: %v", err)
|
|
}
|
|
|
|
if userPin == nil {
|
|
return "", fmt.Errorf("user pin not found")
|
|
}
|
|
|
|
err = bcrypt.CompareHashAndPassword([]byte(userPin.Pin), []byte(oldPin))
|
|
if err != nil {
|
|
return "", fmt.Errorf("incorrect old pin")
|
|
}
|
|
|
|
hashedPin, err := bcrypt.GenerateFromPassword([]byte(newPin), bcrypt.DefaultCost)
|
|
if err != nil {
|
|
return "", fmt.Errorf("error hashing the new pin: %v", err)
|
|
}
|
|
|
|
userPin.Pin = string(hashedPin)
|
|
err = s.UserPinRepo.Update(userPin)
|
|
if err != nil {
|
|
return "", fmt.Errorf("error updating user pin: %v", err)
|
|
}
|
|
|
|
cacheKey := fmt.Sprintf("userpin:%s", userID)
|
|
cacheData := map[string]interface{}{"data": userPin}
|
|
err = utils.SetJSONData(cacheKey, cacheData, time.Hour*24)
|
|
if err != nil {
|
|
fmt.Printf("Error caching updated user pin to Redis: %v\n", err)
|
|
}
|
|
|
|
return "Pin berhasil diperbarui", nil
|
|
}
|