package admin import ( "context" "errors" "git.dmitriygnatenko.ru/dima/go-common/logger" validation "github.com/go-ozzo/ozzo-validation/v4" "github.com/gofiber/fiber/v2" "git.dmitriygnatenko.ru/dima/dmitriygnatenko-v2/internal/dto" customErrors "git.dmitriygnatenko.ru/dima/dmitriygnatenko-v2/internal/helper/errors" "git.dmitriygnatenko.ru/dima/dmitriygnatenko-v2/internal/mapper" "git.dmitriygnatenko.ru/dima/dmitriygnatenko-v2/internal/model" "git.dmitriygnatenko.ru/dima/dmitriygnatenko-v2/internal/service/auth" "git.dmitriygnatenko.ru/dima/dmitriygnatenko-v2/internal/service/i18n" ) type changePasswordPage struct { authService AuthService userRepository UserRepository } func NewChangePasswordPageHandler( authService AuthService, userRepository UserRepository, ) fiber.Handler { h := changePasswordPage{ authService: authService, userRepository: userRepository, } return h.handler() } func (h changePasswordPage) handler() fiber.Handler { return func(fctx *fiber.Ctx) error { ctx := fctx.Context() lang := i18n.LanguageFromContext(fctx) validationErrors := make(map[string]string) var form dto.ChangePasswordForm if fctx.Method() == fiber.MethodPost { if err := fctx.BodyParser(&form); err != nil { logger.Info(ctx, customErrors.Wrap(err, "change user password page: can't parse body").Error()) return err } claims := h.authService.GetClaims(fctx) user, err := h.userRepository.Get(ctx, claims[auth.ClaimNameKey].(string)) if err != nil { logger.Error(ctx, customErrors.Wrap(err, "change user password page: can't get user").Error()) return err } if err := h.validateChangePasswordForm(ctx, form, *user); err != nil { logger.Info(ctx, customErrors.Wrap(err, "change user password page: validation").Error()) validationErrors = mapper.ToErrorsMap(err) } if len(validationErrors) == 0 { newPassword, err := h.authService.GeneratePasswordHash(form.NewPassword) if err != nil { logger.Error( ctx, customErrors.Wrap(err, "change user password page: can't generate new password").Error(), ) return err } if err = h.userRepository.UpdatePassword(ctx, user.ID, newPassword); err != nil { logger.Error( ctx, customErrors.Wrap(err, "change user password page: can't update user").Error(), ) return err } return fctx.Redirect("/admin") } } return fctx.Render("admin/user_change_password", fiber.Map{ "lang": lang, "section": "change_password", "form": form, "errors": validationErrors, }, "admin/_layout") } } func (h changePasswordPage) validateChangePasswordForm( ctx context.Context, req dto.ChangePasswordForm, user model.User, ) error { lang := i18n.DefaultLanguage() requiredMsg := i18n.T(lang, "admin_err_required") lengthMsg := i18n.T(lang, "admin_err_length_255") return validation.ValidateStructWithContext( ctx, &req, validation.Field( &req.OldPassword, validation.Required.Error(requiredMsg), validation.Length(1, 255).Error(lengthMsg), validation.By(h.validateOldPassword(user)), ), validation.Field( &req.NewPassword, validation.Required.Error(requiredMsg), validation.Length(1, 255).Error(lengthMsg), ), ) } func (h changePasswordPage) validateOldPassword(user model.User) func(value interface{}) error { return func(value interface{}) error { oldPassword, _ := value.(string) if !h.authService.IsCorrectPassword(oldPassword, user.Password) { lang := i18n.DefaultLanguage() return errors.New(i18n.T(lang, "admin_err_incorrect_password")) } return nil } }