refact: fixing userpin statement
This commit is contained in:
parent
b741120918
commit
170fc79148
|
@ -1,18 +1,11 @@
|
||||||
package dto
|
package dto
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
type UserPinResponseDTO struct {
|
|
||||||
ID string `json:"id"`
|
|
||||||
UserID string `json:"userId"`
|
|
||||||
Pin string `json:"userpin"`
|
|
||||||
CreatedAt string `json:"createdAt"`
|
|
||||||
UpdatedAt string `json:"updatedAt"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type RequestUserPinDTO struct {
|
type RequestUserPinDTO struct {
|
||||||
Pin string `json:"userpin"`
|
Pin string `json:"userpin"`
|
||||||
}
|
}
|
||||||
|
@ -24,10 +17,8 @@ func (r *RequestUserPinDTO) Validate() (map[string][]string, bool) {
|
||||||
errors["pin"] = append(errors["pin"], "Pin is required")
|
errors["pin"] = append(errors["pin"], "Pin is required")
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(r.Pin) != 6 {
|
if err := validatePin(r.Pin); err != nil {
|
||||||
errors["pin"] = append(errors["pin"], "Pin harus terdiri dari 6 digit")
|
errors["pin"] = append(errors["pin"], err.Error())
|
||||||
} else if !isNumeric(r.Pin) {
|
|
||||||
errors["pin"] = append(errors["pin"], "Pin harus berupa angka")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(errors) > 0 {
|
if len(errors) > 0 {
|
||||||
|
@ -42,17 +33,15 @@ type UpdateUserPinDTO struct {
|
||||||
NewPin string `json:"new_pin"`
|
NewPin string `json:"new_pin"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *UpdateUserPinDTO) Validate() (map[string][]string, bool) {
|
func (u *UpdateUserPinDTO) Validate() (map[string][]string, bool) {
|
||||||
errors := make(map[string][]string)
|
errors := make(map[string][]string)
|
||||||
|
|
||||||
if strings.TrimSpace(r.OldPin) == "" {
|
if strings.TrimSpace(u.OldPin) == "" {
|
||||||
errors["old_pin"] = append(errors["old_pin"], "Old pin is required")
|
errors["old_pin"] = append(errors["old_pin"], "Old pin is required")
|
||||||
}
|
}
|
||||||
|
|
||||||
if strings.TrimSpace(r.NewPin) == "" {
|
if err := validatePin(u.NewPin); err != nil {
|
||||||
errors["new_pin"] = append(errors["new_pin"], "New pin is required")
|
errors["new_pin"] = append(errors["new_pin"], err.Error())
|
||||||
} else if len(r.NewPin) < 6 {
|
|
||||||
errors["new_pin"] = append(errors["new_pin"], "New pin must be at least 6 digits")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(errors) > 0 {
|
if len(errors) > 0 {
|
||||||
|
@ -66,3 +55,12 @@ func isNumeric(s string) bool {
|
||||||
re := regexp.MustCompile(`^[0-9]+$`)
|
re := regexp.MustCompile(`^[0-9]+$`)
|
||||||
return re.MatchString(s)
|
return re.MatchString(s)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func validatePin(pin string) error {
|
||||||
|
if len(pin) != 6 {
|
||||||
|
return fmt.Errorf("pin harus terdiri dari 6 digit")
|
||||||
|
} else if !isNumeric(pin) {
|
||||||
|
return fmt.Errorf("pin harus berupa angka")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@ func (h *UserPinHandler) VerifyUserPin(c *fiber.Ctx) error {
|
||||||
return utils.ValidationErrorResponse(c, map[string][]string{"body": {"Invalid body"}})
|
return utils.ValidationErrorResponse(c, map[string][]string{"body": {"Invalid body"}})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Validasi input pin
|
||||||
errors, valid := requestUserPinDTO.Validate()
|
errors, valid := requestUserPinDTO.Validate()
|
||||||
if !valid {
|
if !valid {
|
||||||
return utils.ValidationErrorResponse(c, errors)
|
return utils.ValidationErrorResponse(c, errors)
|
||||||
|
@ -31,12 +32,12 @@ func (h *UserPinHandler) VerifyUserPin(c *fiber.Ctx) error {
|
||||||
return utils.GenericResponse(c, fiber.StatusUnauthorized, "Unauthorized: User session not found")
|
return utils.GenericResponse(c, fiber.StatusUnauthorized, "Unauthorized: User session not found")
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := h.UserPinService.VerifyUserPin(requestUserPinDTO.Pin, userID)
|
message, err := h.UserPinService.VerifyUserPin(userID, requestUserPinDTO.Pin)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return utils.GenericResponse(c, fiber.StatusUnauthorized, "pin yang anda masukkan salah")
|
return utils.GenericResponse(c, fiber.StatusUnauthorized, err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
return utils.SuccessResponse(c, map[string]string{"data": "pin yang anda masukkan benar"}, "Pin verification successful")
|
return utils.GenericResponse(c, fiber.StatusOK, message)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *UserPinHandler) CheckPinStatus(c *fiber.Ctx) error {
|
func (h *UserPinHandler) CheckPinStatus(c *fiber.Ctx) error {
|
||||||
|
@ -45,16 +46,16 @@ func (h *UserPinHandler) CheckPinStatus(c *fiber.Ctx) error {
|
||||||
return utils.GenericResponse(c, fiber.StatusUnauthorized, "Unauthorized: User session not found")
|
return utils.GenericResponse(c, fiber.StatusUnauthorized, "Unauthorized: User session not found")
|
||||||
}
|
}
|
||||||
|
|
||||||
status, _, err := h.UserPinService.CheckPinStatus(userID)
|
status, err := h.UserPinService.CheckPinStatus(userID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return utils.GenericResponse(c, fiber.StatusInternalServerError, err.Error())
|
return utils.GenericResponse(c, fiber.StatusInternalServerError, err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
if status == "Pin not created" {
|
if status == "Pin not created" {
|
||||||
return utils.GenericResponse(c, fiber.StatusBadRequest, "pin belum dibuat")
|
return utils.GenericResponse(c, fiber.StatusBadRequest, "Pin belum dibuat")
|
||||||
}
|
}
|
||||||
|
|
||||||
return utils.SuccessResponse(c, map[string]string{"data": "pin sudah dibuat"}, "Pin status retrieved successfully")
|
return utils.GenericResponse(c, fiber.StatusOK, "Pin sudah dibuat")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *UserPinHandler) CreateUserPin(c *fiber.Ctx) error {
|
func (h *UserPinHandler) CreateUserPin(c *fiber.Ctx) error {
|
||||||
|
@ -70,12 +71,13 @@ func (h *UserPinHandler) CreateUserPin(c *fiber.Ctx) error {
|
||||||
|
|
||||||
userID := c.Locals("userID").(string)
|
userID := c.Locals("userID").(string)
|
||||||
|
|
||||||
userPinResponse, err := h.UserPinService.CreateUserPin(userID, requestUserPinDTO.Pin)
|
message, err := h.UserPinService.CreateUserPin(userID, requestUserPinDTO.Pin)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
||||||
return utils.GenericResponse(c, fiber.StatusConflict, err.Error())
|
return utils.GenericResponse(c, fiber.StatusConflict, err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
return utils.CreateResponse(c, userPinResponse, "User pin created successfully")
|
return utils.GenericResponse(c, fiber.StatusCreated, message)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *UserPinHandler) UpdateUserPin(c *fiber.Ctx) error {
|
func (h *UserPinHandler) UpdateUserPin(c *fiber.Ctx) error {
|
||||||
|
@ -91,10 +93,10 @@ func (h *UserPinHandler) UpdateUserPin(c *fiber.Ctx) error {
|
||||||
|
|
||||||
userID := c.Locals("userID").(string)
|
userID := c.Locals("userID").(string)
|
||||||
|
|
||||||
userPinResponse, err := h.UserPinService.UpdateUserPin(userID, requestUserPinDTO.OldPin, requestUserPinDTO.NewPin)
|
message, err := h.UserPinService.UpdateUserPin(userID, requestUserPinDTO.OldPin, requestUserPinDTO.NewPin)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return utils.GenericResponse(c, fiber.StatusBadRequest, err.Error())
|
return utils.GenericResponse(c, fiber.StatusBadRequest, err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
return utils.SuccessResponse(c, userPinResponse, "User pin updated successfully")
|
return utils.GenericResponse(c, fiber.StatusOK, message)
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,10 @@ func (r *userPinRepository) FindByUserID(userID string) (*model.UserPin, error)
|
||||||
var userPin model.UserPin
|
var userPin model.UserPin
|
||||||
err := r.DB.Where("user_id = ?", userID).First(&userPin).Error
|
err := r.DB.Where("user_id = ?", userID).First(&userPin).Error
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if err == gorm.ErrRecordNotFound {
|
||||||
|
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &userPin, nil
|
return &userPin, nil
|
||||||
|
|
|
@ -4,7 +4,6 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/pahmiudahgede/senggoldong/dto"
|
|
||||||
"github.com/pahmiudahgede/senggoldong/internal/repositories"
|
"github.com/pahmiudahgede/senggoldong/internal/repositories"
|
||||||
"github.com/pahmiudahgede/senggoldong/model"
|
"github.com/pahmiudahgede/senggoldong/model"
|
||||||
"github.com/pahmiudahgede/senggoldong/utils"
|
"github.com/pahmiudahgede/senggoldong/utils"
|
||||||
|
@ -12,10 +11,10 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type UserPinService interface {
|
type UserPinService interface {
|
||||||
CreateUserPin(userID, pin string) (*dto.UserPinResponseDTO, error)
|
CreateUserPin(userID, pin string) (string, error)
|
||||||
VerifyUserPin(userID, pin string) (*dto.UserPinResponseDTO, error)
|
VerifyUserPin(userID, pin string) (string, error)
|
||||||
CheckPinStatus(userID string) (string, *dto.UserPinResponseDTO, error)
|
CheckPinStatus(userID string) (string, error)
|
||||||
UpdateUserPin(userID, oldPin, newPin string) (*dto.UserPinResponseDTO, error)
|
UpdateUserPin(userID, oldPin, newPin string) (string, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type userPinService struct {
|
type userPinService struct {
|
||||||
|
@ -26,62 +25,53 @@ func NewUserPinService(userPinRepo repositories.UserPinRepository) UserPinServic
|
||||||
return &userPinService{UserPinRepo: userPinRepo}
|
return &userPinService{UserPinRepo: userPinRepo}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *userPinService) VerifyUserPin(pin string, userID string) (*dto.UserPinResponseDTO, error) {
|
func (s *userPinService) VerifyUserPin(userID, pin string) (string, error) {
|
||||||
|
if pin == "" {
|
||||||
|
return "", fmt.Errorf("pin tidak boleh kosong")
|
||||||
|
}
|
||||||
|
|
||||||
userPin, err := s.UserPinRepo.FindByUserID(userID)
|
userPin, err := s.UserPinRepo.FindByUserID(userID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("user pin not found")
|
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))
|
err = bcrypt.CompareHashAndPassword([]byte(userPin.Pin), []byte(pin))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("incorrect pin")
|
return "", fmt.Errorf("incorrect pin")
|
||||||
}
|
}
|
||||||
|
|
||||||
createdAt, _ := utils.FormatDateToIndonesianFormat(userPin.CreatedAt)
|
return "Pin yang anda masukkan benar", nil
|
||||||
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, error) {
|
||||||
}
|
|
||||||
|
|
||||||
func (s *userPinService) CheckPinStatus(userID string) (string, *dto.UserPinResponseDTO, error) {
|
|
||||||
userPin, err := s.UserPinRepo.FindByUserID(userID)
|
userPin, err := s.UserPinRepo.FindByUserID(userID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "Pin not created", nil, nil
|
return "", fmt.Errorf("error checking pin status: %v", err)
|
||||||
|
}
|
||||||
|
if userPin == nil {
|
||||||
|
return "Pin not created", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
createdAt, _ := utils.FormatDateToIndonesianFormat(userPin.CreatedAt)
|
return "Pin already created", nil
|
||||||
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) (string, error) {
|
||||||
}
|
|
||||||
|
|
||||||
func (s *userPinService) CreateUserPin(userID, pin string) (*dto.UserPinResponseDTO, error) {
|
|
||||||
|
|
||||||
existingPin, err := s.UserPinRepo.FindByUserID(userID)
|
existingPin, err := s.UserPinRepo.FindByUserID(userID)
|
||||||
if err != nil && existingPin != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("you have already created a pin, you don't need to create another one")
|
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)
|
hashedPin, err := bcrypt.GenerateFromPassword([]byte(pin), bcrypt.DefaultCost)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("error hashing the pin: %v", err)
|
return "", fmt.Errorf("error hashing the pin: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
newPin := model.UserPin{
|
newPin := model.UserPin{
|
||||||
|
@ -91,74 +81,52 @@ func (s *userPinService) CreateUserPin(userID, pin string) (*dto.UserPinResponse
|
||||||
|
|
||||||
err = s.UserPinRepo.Create(&newPin)
|
err = s.UserPinRepo.Create(&newPin)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("error creating user pin: %v", err)
|
return "", 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)
|
cacheKey := fmt.Sprintf("userpin:%s", userID)
|
||||||
cacheData := map[string]interface{}{
|
cacheData := map[string]interface{}{"data": newPin}
|
||||||
"data": userPinResponse,
|
|
||||||
}
|
|
||||||
err = utils.SetJSONData(cacheKey, cacheData, time.Hour*24)
|
err = utils.SetJSONData(cacheKey, cacheData, time.Hour*24)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("Error caching new user pin to Redis: %v\n", err)
|
fmt.Printf("Error caching new user pin to Redis: %v\n", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return userPinResponse, nil
|
return "Pin berhasil dibuat", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *userPinService) UpdateUserPin(userID, oldPin, newPin string) (*dto.UserPinResponseDTO, error) {
|
func (s *userPinService) UpdateUserPin(userID, oldPin, newPin string) (string, error) {
|
||||||
|
|
||||||
userPin, err := s.UserPinRepo.FindByUserID(userID)
|
userPin, err := s.UserPinRepo.FindByUserID(userID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("user pin not found")
|
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))
|
err = bcrypt.CompareHashAndPassword([]byte(userPin.Pin), []byte(oldPin))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("incorrect old pin")
|
return "", fmt.Errorf("incorrect old pin")
|
||||||
}
|
}
|
||||||
|
|
||||||
hashedPin, err := bcrypt.GenerateFromPassword([]byte(newPin), bcrypt.DefaultCost)
|
hashedPin, err := bcrypt.GenerateFromPassword([]byte(newPin), bcrypt.DefaultCost)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("error hashing the new pin: %v", err)
|
return "", fmt.Errorf("error hashing the new pin: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
userPin.Pin = string(hashedPin)
|
userPin.Pin = string(hashedPin)
|
||||||
err = s.UserPinRepo.Update(userPin)
|
err = s.UserPinRepo.Update(userPin)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("error updating user pin: %v", err)
|
return "", fmt.Errorf("error updating user pin: %v", err)
|
||||||
}
|
|
||||||
|
|
||||||
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,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cacheKey := fmt.Sprintf("userpin:%s", userID)
|
cacheKey := fmt.Sprintf("userpin:%s", userID)
|
||||||
cacheData := map[string]interface{}{
|
cacheData := map[string]interface{}{"data": userPin}
|
||||||
"data": userPinResponse,
|
|
||||||
}
|
|
||||||
err = utils.SetJSONData(cacheKey, cacheData, time.Hour*24)
|
err = utils.SetJSONData(cacheKey, cacheData, time.Hour*24)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("Error caching updated user pin to Redis: %v\n", err)
|
fmt.Printf("Error caching updated user pin to Redis: %v\n", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return userPinResponse, nil
|
return "Pin berhasil diperbarui", nil
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue