api change user password
This commit is contained in:
@@ -3,11 +3,11 @@ package contract
|
||||
import "time"
|
||||
|
||||
const (
|
||||
SettingIncomingLetterPrefix = "INCOMING_LETTER_PREFIX"
|
||||
SettingIncomingLetterSequence = "INCOMING_LETTER_SEQUENCE"
|
||||
SettingIncomingLetterPrefix = "INCOMING_LETTER_PREFIX"
|
||||
SettingIncomingLetterSequence = "INCOMING_LETTER_SEQUENCE"
|
||||
SettingIncomingLetterDepartmentRecipients = "INCOMING_LETTER_DEPARTMENT_RECIPIENTS"
|
||||
SettingOutgoingLetterPrefix = "OUTGOING_LETTER_PREFIX"
|
||||
SettingOutgoingLetterSequence = "OUTGOING_LETTER_SEQUENCE"
|
||||
SettingOutgoingLetterPrefix = "OUTGOING_LETTER_PREFIX"
|
||||
SettingOutgoingLetterSequence = "OUTGOING_LETTER_SEQUENCE"
|
||||
)
|
||||
|
||||
type ErrorResponse struct {
|
||||
@@ -29,6 +29,12 @@ type SuccessResponse struct {
|
||||
Data interface{} `json:"data,omitempty"`
|
||||
}
|
||||
|
||||
type NewSuccessResponse struct {
|
||||
Success bool `json:"success"`
|
||||
Message string `json:"message"`
|
||||
Data interface{} `json:"data,omitempty"`
|
||||
}
|
||||
|
||||
type PaginationRequest struct {
|
||||
Page int `json:"page" validate:"min=1"`
|
||||
Limit int `json:"limit" validate:"min=1,max=100"`
|
||||
|
||||
@@ -7,17 +7,17 @@ import (
|
||||
)
|
||||
|
||||
type CreateUserRequest struct {
|
||||
Name string `json:"name" validate:"required,min=1,max=255"`
|
||||
Email string `json:"email" validate:"required,email"`
|
||||
Password string `json:"password" validate:"required,min=6"`
|
||||
RoleID *uuid.UUID `json:"role_id,omitempty" validate:"required"`
|
||||
Name string `json:"name" validate:"required,min=1,max=255"`
|
||||
Email string `json:"email" validate:"required,email"`
|
||||
Password string `json:"password" validate:"required,min=6"`
|
||||
RoleID *uuid.UUID `json:"role_id,omitempty" validate:"required"`
|
||||
DepartmentIDs []uuid.UUID `json:"department_ids,omitempty"`
|
||||
}
|
||||
|
||||
type UpdateUserRequest struct {
|
||||
Name *string `json:"name,omitempty" validate:"omitempty,min=1,max=255"`
|
||||
Email *string `json:"email,omitempty" validate:"omitempty,email"`
|
||||
Role *uuid.UUID `json:"role,omitempty"`
|
||||
Role *uuid.UUID `json:"role,omitempty"`
|
||||
IsActive *bool `json:"is_active,omitempty"`
|
||||
Permissions *map[string]interface{} `json:"permissions,omitempty"`
|
||||
DepartmentIDs *[]uuid.UUID `json:"department_ids,omitempty"`
|
||||
@@ -28,6 +28,10 @@ type ChangePasswordRequest struct {
|
||||
NewPassword string `json:"new_password" validate:"required,min=6"`
|
||||
}
|
||||
|
||||
type ChangeUserPasswordRequest struct {
|
||||
NewPassword string `json:"new_password" validate:"required,min=6"`
|
||||
}
|
||||
|
||||
type UpdateUserOutletRequest struct {
|
||||
OutletID uuid.UUID `json:"outlet_id" validate:"required"`
|
||||
}
|
||||
@@ -105,9 +109,9 @@ type CreateDepartmentRequest struct {
|
||||
}
|
||||
|
||||
type UpdateDepartmentRequest struct {
|
||||
Name *string `json:"name,omitempty" validate:"omitempty,min=1,max=255"`
|
||||
Code *string `json:"code,omitempty" validate:"omitempty,min=1,max=50"`
|
||||
ParentID *uuid.UUID `json:"parent_id,omitempty"`
|
||||
Name *string `json:"name,omitempty" validate:"omitempty,min=1,max=255"`
|
||||
Code *string `json:"code,omitempty" validate:"omitempty,min=1,max=50"`
|
||||
ParentID *uuid.UUID `json:"parent_id,omitempty"`
|
||||
}
|
||||
|
||||
type GetDepartmentResponse struct {
|
||||
|
||||
@@ -249,6 +249,40 @@ func (h *UserHandler) ChangePassword(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, &contract.SuccessResponse{Message: "Password changed successfully"})
|
||||
}
|
||||
|
||||
func (h *UserHandler) ChangeUserPassword(c *gin.Context) {
|
||||
userIDStr := c.Param("id")
|
||||
userID, err := uuid.Parse(userIDStr)
|
||||
if err != nil {
|
||||
logger.FromContext(c).WithError(err).Error("UserHandler::ChangeUserPassword -> Invalid user ID")
|
||||
h.sendValidationErrorResponse(c, "Invalid user ID", constants.MalformedFieldErrorCode)
|
||||
return
|
||||
}
|
||||
|
||||
validationError, validationErrorCode := h.userValidator.ValidateUserID(userID)
|
||||
if validationError != nil {
|
||||
logger.FromContext(c).WithError(validationError).Error("UserHandler::ChangeUserPassword -> user ID validation failed")
|
||||
h.sendValidationErrorResponse(c, validationError.Error(), validationErrorCode)
|
||||
return
|
||||
}
|
||||
|
||||
var req contract.ChangeUserPasswordRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
logger.FromContext(c).WithError(err).Error("UserHandler::ChangeUserPassword -> request binding failed")
|
||||
h.sendValidationErrorResponse(c, "Invalid request body", constants.MissingFieldErrorCode)
|
||||
return
|
||||
}
|
||||
|
||||
err = h.userService.ChangeUserPassword(c.Request.Context(), userID, &req)
|
||||
if err != nil {
|
||||
logger.FromContext(c).WithError(err).Error("UserHandler::ChangeUserPassword -> Failed to change password from service")
|
||||
h.sendErrorResponse(c, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
logger.FromContext(c).Info("UserHandler::ChangeUserPassword -> Successfully changed password")
|
||||
c.JSON(http.StatusOK, &contract.NewSuccessResponse{Success: true, Message: "Password changed successfully"})
|
||||
}
|
||||
|
||||
func (h *UserHandler) GetProfile(c *gin.Context) {
|
||||
appCtx := appcontext.FromGinContext(c.Request.Context())
|
||||
if appCtx.UserID == uuid.Nil {
|
||||
|
||||
@@ -15,6 +15,7 @@ type UserService interface {
|
||||
GetUserByEmail(ctx context.Context, email string) (*contract.UserResponse, error)
|
||||
ListUsers(ctx context.Context, req *contract.ListUsersRequest) (*contract.ListUsersResponse, error)
|
||||
ChangePassword(ctx context.Context, userID uuid.UUID, req *contract.ChangePasswordRequest) error
|
||||
ChangeUserPassword(ctx context.Context, userID uuid.UUID, req *contract.ChangeUserPasswordRequest) error
|
||||
|
||||
GetProfile(ctx context.Context, userID uuid.UUID) (*contract.UserProfileResponse, error)
|
||||
UpdateProfile(ctx context.Context, userID uuid.UUID, req *contract.UpdateUserProfileRequest) (*contract.UserProfileResponse, error)
|
||||
|
||||
@@ -125,7 +125,7 @@ func (p *UserProcessorImpl) UpdateUser(ctx context.Context, id uuid.UUID, req *c
|
||||
return nil, fmt.Errorf("failed to update user: %w", err)
|
||||
}
|
||||
|
||||
if(req.Name != nil) {
|
||||
if req.Name != nil {
|
||||
profile, err := p.profileRepo.GetByUserID(ctx, updated.ID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get user profile: %w", err)
|
||||
@@ -293,6 +293,25 @@ func (p *UserProcessorImpl) ChangePassword(ctx context.Context, userID uuid.UUID
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *UserProcessorImpl) ChangeUserPassword(ctx context.Context, userID uuid.UUID, req *contract.ChangeUserPasswordRequest) error {
|
||||
_, err := p.userRepo.GetByID(ctx, userID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("user not found: %w", err)
|
||||
}
|
||||
|
||||
newPasswordHash, err := bcrypt.GenerateFromPassword([]byte(req.NewPassword), bcrypt.DefaultCost)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to hash new password: %w", err)
|
||||
}
|
||||
|
||||
err = p.userRepo.UpdatePassword(ctx, userID, string(newPasswordHash))
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to update password: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *UserProcessorImpl) ActivateUser(ctx context.Context, userID uuid.UUID) error {
|
||||
_, err := p.userRepo.GetByID(ctx, userID)
|
||||
if err != nil {
|
||||
|
||||
@@ -15,6 +15,7 @@ type UserHandler interface {
|
||||
GetUserProfile(c *gin.Context)
|
||||
UpdateProfile(c *gin.Context)
|
||||
ChangePassword(c *gin.Context)
|
||||
ChangeUserPassword(c *gin.Context)
|
||||
ListTitles(c *gin.Context)
|
||||
GetActiveUsersForMention(c *gin.Context)
|
||||
}
|
||||
|
||||
@@ -103,6 +103,7 @@ func (r *Router) addAppRoutes(rg *gin.Engine) {
|
||||
users.GET("/:id/profile", r.userHandler.GetUserProfile)
|
||||
users.PUT("/profile", r.userHandler.UpdateProfile)
|
||||
users.PUT("/:id/password", r.userHandler.ChangePassword)
|
||||
users.PUT("/:id/user-password", r.userHandler.ChangeUserPassword)
|
||||
users.GET("/titles", r.userHandler.ListTitles)
|
||||
users.GET("/mention", r.userHandler.GetActiveUsersForMention)
|
||||
users.POST("/profile/avatar", r.fileHandler.UploadProfileAvatar)
|
||||
|
||||
@@ -17,6 +17,7 @@ type UserProcessor interface {
|
||||
GetUserByEmail(ctx context.Context, email string) (*contract.UserResponse, error)
|
||||
GetUserEntityByEmail(ctx context.Context, email string) (*entities.User, error)
|
||||
ChangePassword(ctx context.Context, userID uuid.UUID, req *contract.ChangePasswordRequest) error
|
||||
ChangeUserPassword(ctx context.Context, userID uuid.UUID, req *contract.ChangeUserPasswordRequest) error
|
||||
|
||||
GetUserRoles(ctx context.Context, userID uuid.UUID) ([]contract.RoleResponse, error)
|
||||
GetUserPermissionCodes(ctx context.Context, userID uuid.UUID) ([]string, error)
|
||||
|
||||
@@ -52,7 +52,7 @@ func (s *UserServiceImpl) ListUsers(ctx context.Context, req *contract.ListUsers
|
||||
if page <= 0 {
|
||||
page = 1
|
||||
}
|
||||
|
||||
|
||||
limit := req.Limit
|
||||
if limit <= 0 {
|
||||
limit = 10
|
||||
@@ -60,7 +60,7 @@ func (s *UserServiceImpl) ListUsers(ctx context.Context, req *contract.ListUsers
|
||||
if limit > 100 {
|
||||
limit = 100 // Max limit to prevent performance issues
|
||||
}
|
||||
|
||||
|
||||
offset := (page - 1) * limit
|
||||
|
||||
// Pass calculated offset and limit to processor
|
||||
@@ -79,6 +79,10 @@ func (s *UserServiceImpl) ChangePassword(ctx context.Context, userID uuid.UUID,
|
||||
return s.userProcessor.ChangePassword(ctx, userID, req)
|
||||
}
|
||||
|
||||
func (s *UserServiceImpl) ChangeUserPassword(ctx context.Context, userID uuid.UUID, req *contract.ChangeUserPasswordRequest) error {
|
||||
return s.userProcessor.ChangeUserPassword(ctx, userID, req)
|
||||
}
|
||||
|
||||
func (s *UserServiceImpl) GetProfile(ctx context.Context, userID uuid.UUID) (*contract.UserProfileResponse, error) {
|
||||
prof, err := s.userProcessor.GetUserProfile(ctx, userID)
|
||||
if err != nil {
|
||||
@@ -114,6 +118,6 @@ func (s *UserServiceImpl) GetActiveUsersForMention(ctx context.Context, search *
|
||||
if limit > 100 {
|
||||
limit = 100 // Max limit to prevent performance issues
|
||||
}
|
||||
|
||||
|
||||
return s.userProcessor.GetActiveUsersForMention(ctx, search, limit)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user