feat: add feature update user and update password

This commit is contained in:
pahmiudahgede 2024-12-08 17:00:37 +07:00
parent 601dc1d088
commit add86d7d83
5 changed files with 243 additions and 10 deletions

View File

@ -44,12 +44,13 @@ func ValidatePassword(password string) error {
}
type RegisterUserInput struct {
Username string `json:"username"`
Name string `json:"name"`
Email string `json:"email"`
Phone string `json:"phone"`
Password string `json:"password"`
RoleId string `json:"roleId"`
Username string `json:"username"`
Name string `json:"name"`
Email string `json:"email"`
Phone string `json:"phone"`
Password string `json:"password"`
ConfirmPassword string `json:"confirm_password"`
RoleId string `json:"roleId"`
}
func (input *RegisterUserInput) Validate() error {
@ -74,9 +75,67 @@ func (input *RegisterUserInput) Validate() error {
return err
}
if input.Password != input.ConfirmPassword {
return errors.New("password dan confirm password tidak cocok")
}
if input.RoleId == "" {
return errors.New("roleId harus diisi")
}
return nil
}
type UpdatePasswordInput struct {
OldPassword string `json:"old_password"`
NewPassword string `json:"new_password"`
}
func (input *UpdatePasswordInput) Validate() error {
if input.OldPassword == "" {
return errors.New("old password must be provided")
}
if input.NewPassword == "" {
return errors.New("new password must be provided")
}
if len(input.NewPassword) < 8 {
return errors.New("new password must be at least 8 characters long")
}
return nil
}
type UpdateUserInput struct {
Email string `json:"email"`
Username string `json:"username"`
Name string `json:"name"`
Phone string `json:"phone"`
}
func (input *UpdateUserInput) Validate() error {
if input.Email != "" {
if err := ValidateEmail(input.Email); err != nil {
return err
}
}
if input.Username == "" {
return errors.New("username harus diisi")
}
if input.Name == "" {
return errors.New("name harus diisi")
}
if input.Phone != "" {
if err := ValidatePhone(input.Phone); err != nil {
return err
}
}
return nil
}

View File

@ -11,6 +11,8 @@ func AppRouter(app *fiber.App) {
app.Post("/login", controllers.Login)
app.Get("/user", middleware.AuthMiddleware, controllers.GetUserInfo)
app.Put("/update-user", middleware.AuthMiddleware, controllers.UpdateUser)
app.Post("/user/update-password", middleware.AuthMiddleware, controllers.UpdatePassword)
app.Get("/list-address", middleware.AuthMiddleware, controllers.GetListAddress)
app.Get("/address/:id", middleware.AuthMiddleware, controllers.GetAddressByID)

View File

@ -27,9 +27,8 @@ func Register(c *fiber.Ctx) error {
))
}
err := services.RegisterUser(userInput.Username, userInput.Name, userInput.Email, userInput.Phone, userInput.Password, userInput.RoleId)
err := services.RegisterUser(userInput.Username, userInput.Name, userInput.Email, userInput.Phone, userInput.Password, userInput.ConfirmPassword, userInput.RoleId)
if err != nil {
if err.Error() == "email is already registered" {
return c.Status(fiber.StatusConflict).JSON(utils.FormatResponse(
fiber.StatusConflict,
@ -51,6 +50,13 @@ func Register(c *fiber.Ctx) error {
nil,
))
}
if err.Error() == "password dan confirm password tidak cocok" {
return c.Status(fiber.StatusBadRequest).JSON(utils.FormatResponse(
fiber.StatusBadRequest,
"Password dan confirm password tidak cocok",
nil,
))
}
return c.Status(fiber.StatusInternalServerError).JSON(utils.FormatResponse(
fiber.StatusInternalServerError,
@ -149,3 +155,77 @@ func GetUserInfo(c *fiber.Ctx) error {
userResponse,
))
}
func UpdateUser(c *fiber.Ctx) error {
var userInput dto.UpdateUserInput
if err := c.BodyParser(&userInput); err != nil {
return c.Status(fiber.StatusBadRequest).JSON(utils.FormatResponse(
fiber.StatusBadRequest,
"Invalid input data",
nil,
))
}
if err := userInput.Validate(); err != nil {
return c.Status(fiber.StatusBadRequest).JSON(utils.FormatResponse(
fiber.StatusBadRequest,
err.Error(),
nil,
))
}
userID := c.Locals("userID").(string)
err := services.UpdateUser(userID, userInput.Email, userInput.Username, userInput.Name, userInput.Phone)
if err != nil {
return c.Status(fiber.StatusInternalServerError).JSON(utils.FormatResponse(
fiber.StatusInternalServerError,
err.Error(),
nil,
))
}
return c.Status(fiber.StatusOK).JSON(utils.FormatResponse(
fiber.StatusOK,
"User updated successfully",
nil,
))
}
func UpdatePassword(c *fiber.Ctx) error {
var passwordInput dto.UpdatePasswordInput
if err := c.BodyParser(&passwordInput); err != nil {
return c.Status(fiber.StatusBadRequest).JSON(utils.FormatResponse(
fiber.StatusBadRequest,
"Invalid input data",
nil,
))
}
if err := passwordInput.Validate(); err != nil {
return c.Status(fiber.StatusBadRequest).JSON(utils.FormatResponse(
fiber.StatusBadRequest,
err.Error(),
nil,
))
}
userID := c.Locals("userID").(string)
err := services.UpdatePassword(userID, passwordInput.OldPassword, passwordInput.NewPassword)
if err != nil {
return c.Status(fiber.StatusInternalServerError).JSON(utils.FormatResponse(
fiber.StatusInternalServerError,
err.Error(),
nil,
))
}
return c.Status(fiber.StatusOK).JSON(utils.FormatResponse(
fiber.StatusOK,
"Password updated successfully",
nil,
))
}

View File

@ -83,3 +83,26 @@ func GetUserByID(userID string) (domain.User, error) {
return user, nil
}
func UpdateUser(user *domain.User) error {
if err := config.DB.Save(user).Error; err != nil {
return errors.New("failed to save user")
}
return nil
}
func UpdateUserPassword(userID, newPassword string) error {
var user domain.User
if err := config.DB.Where("id = ?", userID).First(&user).Error; err != nil {
return errors.New("user not found")
}
user.Password = newPassword
if err := config.DB.Save(&user).Error; err != nil {
return errors.New("failed to update password")
}
return nil
}

View File

@ -11,7 +11,10 @@ import (
"golang.org/x/crypto/bcrypt"
)
func RegisterUser(username, name, email, phone, password, roleId string) error {
func RegisterUser(username, name, email, phone, password, confirmPassword, roleId string) error {
if password != confirmPassword {
return errors.New("password dan confirm password tidak cocok")
}
if repositories.IsEmailExist(email) {
return errors.New("email is already registered")
@ -46,7 +49,8 @@ func LoginUser(emailOrUsername, password string) (string, error) {
return "", errors.New("invalid email/username or password")
}
if err := bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(password)); err != nil {
err = bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(password))
if err != nil {
return "", errors.New("invalid email/username or password")
}
@ -78,3 +82,68 @@ func GetUserByID(userID string) (domain.User, error) {
}
return user, nil
}
func UpdateUser(userID, email, username, name, phone string) error {
user, err := repositories.GetUserByID(userID)
if err != nil {
return errors.New("user not found")
}
if email != "" && email != user.Email && repositories.IsEmailExist(email) {
return errors.New("email is already registered")
}
if username != "" && username != user.Username && repositories.IsUsernameExist(username) {
return errors.New("username is already registered")
}
if phone != "" && phone != user.Phone && repositories.IsPhoneExist(phone) {
return errors.New("phone number is already registered")
}
if email != "" {
user.Email = email
}
if username != "" {
user.Username = username
}
if name != "" {
user.Name = name
}
if phone != "" {
user.Phone = phone
}
err = repositories.UpdateUser(&user)
if err != nil {
return errors.New("failed to update user")
}
return nil
}
func UpdatePassword(userID, oldPassword, newPassword string) error {
user, err := repositories.GetUserByID(userID)
if err != nil {
return errors.New("user not found")
}
err = bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(oldPassword))
if err != nil {
return errors.New("old password is incorrect")
}
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(newPassword), bcrypt.DefaultCost)
if err != nil {
return errors.New("failed to hash new password")
}
err = repositories.UpdateUserPassword(userID, string(hashedPassword))
if err != nil {
return errors.New("failed to update password")
}
return nil
}