feat: add feature update userpin
This commit is contained in:
parent
bb85fe64d7
commit
4f97664a6c
|
@ -37,6 +37,31 @@ func (r *RequestUserPinDTO) Validate() (map[string][]string, bool) {
|
|||
return nil, true
|
||||
}
|
||||
|
||||
type UpdateUserPinDTO struct {
|
||||
OldPin string `json:"old_pin"`
|
||||
NewPin string `json:"new_pin"`
|
||||
}
|
||||
|
||||
func (r *UpdateUserPinDTO) Validate() (map[string][]string, bool) {
|
||||
errors := make(map[string][]string)
|
||||
|
||||
if strings.TrimSpace(r.OldPin) == "" {
|
||||
errors["old_pin"] = append(errors["old_pin"], "Old pin is required")
|
||||
}
|
||||
|
||||
if strings.TrimSpace(r.NewPin) == "" {
|
||||
errors["new_pin"] = append(errors["new_pin"], "New pin is required")
|
||||
} 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 {
|
||||
return errors, false
|
||||
}
|
||||
|
||||
return nil, true
|
||||
}
|
||||
|
||||
func isNumeric(s string) bool {
|
||||
re := regexp.MustCompile(`^[0-9]+$`)
|
||||
return re.MatchString(s)
|
||||
|
|
|
@ -77,3 +77,24 @@ func (h *UserPinHandler) CreateUserPin(c *fiber.Ctx) error {
|
|||
|
||||
return utils.LogResponse(c, userPinResponse, "User pin created successfully")
|
||||
}
|
||||
|
||||
func (h *UserPinHandler) UpdateUserPin(c *fiber.Ctx) error {
|
||||
var requestUserPinDTO dto.UpdateUserPinDTO
|
||||
if err := c.BodyParser(&requestUserPinDTO); err != nil {
|
||||
return utils.ValidationErrorResponse(c, map[string][]string{"body": {"Invalid body"}})
|
||||
}
|
||||
|
||||
errors, valid := requestUserPinDTO.Validate()
|
||||
if !valid {
|
||||
return utils.ValidationErrorResponse(c, errors)
|
||||
}
|
||||
|
||||
userID := c.Locals("userID").(string)
|
||||
|
||||
userPinResponse, err := h.UserPinService.UpdateUserPin(userID, requestUserPinDTO.OldPin, requestUserPinDTO.NewPin)
|
||||
if err != nil {
|
||||
return utils.GenericErrorResponse(c, fiber.StatusBadRequest, err.Error())
|
||||
}
|
||||
|
||||
return utils.LogResponse(c, userPinResponse, "User pin updated successfully")
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ type UserPinRepository interface {
|
|||
FindByUserID(userID string) (*model.UserPin, error)
|
||||
FindByPin(userPin string) (*model.UserPin, error)
|
||||
Create(userPin *model.UserPin) error
|
||||
Update(userPin *model.UserPin) error
|
||||
}
|
||||
|
||||
type userPinRepository struct {
|
||||
|
@ -44,3 +45,11 @@ func (r *userPinRepository) Create(userPin *model.UserPin) error {
|
|||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *userPinRepository) Update(userPin *model.UserPin) error {
|
||||
err := r.DB.Save(userPin).Error
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
|
@ -15,6 +15,7 @@ type UserPinService interface {
|
|||
CreateUserPin(userID, pin string) (*dto.UserPinResponseDTO, error)
|
||||
VerifyUserPin(userID, pin string) (*dto.UserPinResponseDTO, error)
|
||||
CheckPinStatus(userID string) (string, *dto.UserPinResponseDTO, error)
|
||||
UpdateUserPin(userID, oldPin, newPin string) (*dto.UserPinResponseDTO, error)
|
||||
}
|
||||
|
||||
type userPinService struct {
|
||||
|
@ -115,3 +116,49 @@ func (s *userPinService) CreateUserPin(userID, pin string) (*dto.UserPinResponse
|
|||
|
||||
return userPinResponse, nil
|
||||
}
|
||||
|
||||
func (s *userPinService) UpdateUserPin(userID, oldPin, newPin 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(oldPin))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("incorrect old pin")
|
||||
}
|
||||
|
||||
hashedPin, err := bcrypt.GenerateFromPassword([]byte(newPin), bcrypt.DefaultCost)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error hashing the new pin: %v", err)
|
||||
}
|
||||
|
||||
userPin.Pin = string(hashedPin)
|
||||
err = s.UserPinRepo.Update(userPin)
|
||||
if err != nil {
|
||||
return nil, 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)
|
||||
cacheData := map[string]interface{}{
|
||||
"data": userPinResponse,
|
||||
}
|
||||
err = utils.SetJSONData(cacheKey, cacheData, time.Hour*24)
|
||||
if err != nil {
|
||||
fmt.Printf("Error caching updated user pin to Redis: %v\n", err)
|
||||
}
|
||||
|
||||
return userPinResponse, nil
|
||||
}
|
||||
|
|
|
@ -16,6 +16,6 @@ func UserProfileRouter(api fiber.Router) {
|
|||
|
||||
api.Get("/user", middleware.AuthMiddleware, userProfileHandler.GetUserProfile)
|
||||
api.Put("/user/update-user", middleware.AuthMiddleware, userProfileHandler.UpdateUserProfile)
|
||||
api.Post("/user/update-user-password", middleware.AuthMiddleware, userProfileHandler.UpdateUserPassword)
|
||||
api.Put("/user/upload-photoprofile", middleware.AuthMiddleware, userProfileHandler.UpdateUserAvatar)
|
||||
api.Patch("/user/update-user-password", middleware.AuthMiddleware, userProfileHandler.UpdateUserPassword)
|
||||
api.Patch("/user/upload-photoprofile", middleware.AuthMiddleware, userProfileHandler.UpdateUserAvatar)
|
||||
}
|
||||
|
|
|
@ -20,5 +20,5 @@ func UserPinRouter(api fiber.Router) {
|
|||
api.Post("/user/set-pin", middleware.AuthMiddleware, userPinHandler.CreateUserPin)
|
||||
api.Post("/user/verif-pin", middleware.AuthMiddleware, userPinHandler.VerifyUserPin)
|
||||
api.Get("/user/cek-pin-status", middleware.AuthMiddleware, userPinHandler.CheckPinStatus)
|
||||
|
||||
api.Patch("/user/update-pin", middleware.AuthMiddleware, userPinHandler.UpdateUserPin)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue