From 39145cac17722edcb2254c9738c2b2add34652ec Mon Sep 17 00:00:00 2001 From: RianIhsan Date: Thu, 9 Nov 2023 22:49:47 +0700 Subject: [PATCH] feature: resend otp --- go.mod | 2 +- module/auth/domain/request.go | 4 ++++ module/auth/handler/handler.go | 32 +++++++++++++++++++++++++++- module/auth/interface.go | 3 +++ module/auth/repository/repository.go | 11 +++++++++- module/auth/service/service.go | 29 ++++++++++++++++++++++++- routes/routes.go | 1 + 7 files changed, 78 insertions(+), 4 deletions(-) diff --git a/go.mod b/go.mod index 7315052..3df242e 100644 --- a/go.mod +++ b/go.mod @@ -9,6 +9,7 @@ require ( github.com/labstack/echo/v4 v4.11.2 github.com/sirupsen/logrus v1.9.3 github.com/stretchr/testify v1.8.4 + github.com/wneessen/go-mail v0.4.0 golang.org/x/crypto v0.14.0 gorm.io/driver/mysql v1.5.2 gorm.io/gorm v1.25.5 @@ -30,7 +31,6 @@ require ( github.com/stretchr/objx v0.5.0 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/valyala/fasttemplate v1.2.2 // indirect - github.com/wneessen/go-mail v0.4.0 // indirect golang.org/x/net v0.17.0 // indirect golang.org/x/sys v0.13.0 // indirect golang.org/x/text v0.13.0 // indirect diff --git a/module/auth/domain/request.go b/module/auth/domain/request.go index 179a9b0..17fcb65 100644 --- a/module/auth/domain/request.go +++ b/module/auth/domain/request.go @@ -14,3 +14,7 @@ type EmailRequest struct { Email string `form:"email" json:"email" validate:"required"` OTP string `form:"otp" json:"otp" validate:"required"` } + +type ResendOTPRequest struct { + Email string `form:"email" json:"email" validate:"required"` +} diff --git a/module/auth/handler/handler.go b/module/auth/handler/handler.go index 9281508..3c3cff8 100644 --- a/module/auth/handler/handler.go +++ b/module/auth/handler/handler.go @@ -1,15 +1,17 @@ package handler import ( + "net/http" + "github.com/capstone-kelompok-7/backend-disappear/module/auth" "github.com/capstone-kelompok-7/backend-disappear/module/auth/domain" "github.com/capstone-kelompok-7/backend-disappear/module/users" user "github.com/capstone-kelompok-7/backend-disappear/module/users/domain" "github.com/capstone-kelompok-7/backend-disappear/utils" + "github.com/capstone-kelompok-7/backend-disappear/utils/email" "github.com/capstone-kelompok-7/backend-disappear/utils/response" "github.com/labstack/echo/v4" "github.com/sirupsen/logrus" - "net/http" ) type AuthHandler struct { @@ -104,3 +106,31 @@ func (h *AuthHandler) VerifyEmail() echo.HandlerFunc { return response.SendStatusOkResponse(c, "Email berhasil diverifikasi!, Silahkan login.") } } + +func (h *AuthHandler) ResendOTP() echo.HandlerFunc { + return func(c echo.Context) error { + var emailRequest domain.ResendOTPRequest + + if err := c.Bind(&emailRequest); err != nil { + return response.SendErrorResponse(c, http.StatusBadRequest, "Format input yang Anda masukkan tidak sesuai.") + } + + if err := utils.ValidateStruct(emailRequest); err != nil { + return response.SendErrorResponse(c, http.StatusBadRequest, "Validasi gagal: "+err.Error()) + } + + newOTP, err := h.service.ResendOTP(emailRequest.Email) + if err != nil { + return response.SendErrorResponse(c, http.StatusBadRequest, "Gagal mengirim OTP: "+err.Error()) + } + + err = email.EmaiilService(emailRequest.Email, newOTP.OTP) + if err != nil { + return response.SendErrorResponse(c, http.StatusBadRequest, "Gagal mengirim OTP ke email: "+err.Error()) + + } + + return response.SendStatusOkResponse(c, "OTP berhasil dikirim kembali!, Silahkan cek email anda.") + + } +} diff --git a/module/auth/interface.go b/module/auth/interface.go index 605f296..654e142 100644 --- a/module/auth/interface.go +++ b/module/auth/interface.go @@ -12,16 +12,19 @@ type RepositoryAuthInterface interface { UpdateUser(user *domain.UserModels) (*domain.UserModels, error) FindValidOTP(userID int, otp string) (*domain.OTPModels, error) DeleteOTP(otp *domain.OTPModels) error + DeleteUserOTP(userId uint64) error } type ServiceAuthInterface interface { Register(newData *domain.UserModels) (*domain.UserModels, error) Login(email, password string) (*domain.UserModels, string, error) VerifyEmail(email, otp string) error + ResendOTP(email string) (*domain.OTPModels, error) } type HandlerAuthInterface interface { Register() echo.HandlerFunc Login() echo.HandlerFunc VerifyEmail() echo.HandlerFunc + ResendOTP() echo.HandlerFunc } diff --git a/module/auth/repository/repository.go b/module/auth/repository/repository.go index 04d1d9b..1861ed1 100644 --- a/module/auth/repository/repository.go +++ b/module/auth/repository/repository.go @@ -1,10 +1,11 @@ package repository import ( + "time" + "github.com/capstone-kelompok-7/backend-disappear/module/auth" "github.com/capstone-kelompok-7/backend-disappear/module/users/domain" "gorm.io/gorm" - "time" ) type AuthRepository struct { @@ -65,3 +66,11 @@ func (r *AuthRepository) DeleteOTP(otp *domain.OTPModels) error { } return nil } + +func (r *AuthRepository) DeleteUserOTP(userId uint64) error { + if err := r.db.Where("user_id = ?", userId).Delete(&domain.OTPModels{}).Error; err != nil { + return err + } + + return nil +} diff --git a/module/auth/service/service.go b/module/auth/service/service.go index 76d025d..86ceccb 100644 --- a/module/auth/service/service.go +++ b/module/auth/service/service.go @@ -2,13 +2,14 @@ package service import ( "errors" + "time" + "github.com/capstone-kelompok-7/backend-disappear/module/auth" "github.com/capstone-kelompok-7/backend-disappear/module/users" "github.com/capstone-kelompok-7/backend-disappear/module/users/domain" "github.com/capstone-kelompok-7/backend-disappear/utils" "github.com/capstone-kelompok-7/backend-disappear/utils/email" "github.com/capstone-kelompok-7/backend-disappear/utils/otp" - "time" ) type AuthService struct { @@ -114,3 +115,29 @@ func (s *AuthService) VerifyEmail(email, otp string) error { return nil } + +func (s *AuthService) ResendOTP(email string) (*domain.OTPModels, error) { + user, err := s.userService.GetUsersByEmail(email) + if err != nil { + return nil, err + } + if user.ID == 0 { + return nil, errors.New("user tidak ditemukan pada email ini") + } + errDeleteOTP := s.repo.DeleteUserOTP(user.ID) + if errDeleteOTP != nil { + return nil, errDeleteOTP + } + generateOTP := otp.GenerateRandomOTP(6) + newOTP := &domain.OTPModels{ + UserID: int(user.ID), + OTP: generateOTP, + ExpiredOTP: time.Now().Add(2 * time.Minute).Unix(), + } + + _, err = s.repo.SaveOTP(newOTP) + if err != nil { + return nil, err + } + return newOTP, nil +} diff --git a/routes/routes.go b/routes/routes.go index 71c2af2..3a64ef1 100644 --- a/routes/routes.go +++ b/routes/routes.go @@ -18,6 +18,7 @@ func RouteAuth(e *echo.Echo, h auth.HandlerAuthInterface) { e.POST("api/v1/auth/register", h.Register()) e.POST("api/v1/auth/login", h.Login()) e.POST("/api/v1/auth/verify", h.VerifyEmail()) + e.POST("/api/v1/auth/resend-otp", h.ResendOTP()) } func RouteUser(e *echo.Echo, h users.HandlerUserInterface, jwtService utils.JWTInterface, userService users.ServiceUserInterface) {