diff --git a/src/main/java/ru/ulstu/configuration/Constants.java b/src/main/java/ru/ulstu/configuration/Constants.java index 51806b6..f910108 100644 --- a/src/main/java/ru/ulstu/configuration/Constants.java +++ b/src/main/java/ru/ulstu/configuration/Constants.java @@ -6,6 +6,7 @@ public class Constants { public static final String MAIL_ACTIVATE = "Account activation"; public static final String MAIL_RESET = "Password reset"; public static final String MAIL_INVITE = "Account registration"; + public static final String MAIL_CHANGE_PASSWORD = "Password has been changed"; public static final int MIN_PASSWORD_LENGTH = 6; public static final int MAX_PASSWORD_LENGTH = 32; diff --git a/src/main/java/ru/ulstu/core/model/ErrorConstants.java b/src/main/java/ru/ulstu/core/model/ErrorConstants.java index ad69b86..4347dfd 100644 --- a/src/main/java/ru/ulstu/core/model/ErrorConstants.java +++ b/src/main/java/ru/ulstu/core/model/ErrorConstants.java @@ -8,7 +8,7 @@ public enum ErrorConstants { USER_ACTIVATION_ERROR(101, "Invalid activation key"), USER_EMAIL_EXISTS(102, "User with same email already exists"), USER_LOGIN_EXISTS(103, "User with same login already exists"), - USER_PASSWORDS_NOT_VALID_OR_NOT_MATCH(104, "User passwords is not valid or not match"), + USER_PASSWORDS_NOT_VALID_OR_NOT_MATCH(104, "Пароли введены неверно"), USER_NOT_FOUND(105, "User is not found"), USER_NOT_ACTIVATED(106, "User is not activated"), USER_RESET_ERROR(107, "Invalid reset key"), diff --git a/src/main/java/ru/ulstu/core/model/response/Response.java b/src/main/java/ru/ulstu/core/model/response/Response.java index 4722010..7c57168 100644 --- a/src/main/java/ru/ulstu/core/model/response/Response.java +++ b/src/main/java/ru/ulstu/core/model/response/Response.java @@ -11,6 +11,6 @@ public class Response extends ResponseEntity { } public Response(ErrorConstants error) { - super(new ControllerResponse(new ControllerResponseError<>(error, null)), HttpStatus.OK); + super(new ControllerResponse(new ControllerResponseError<>(error, null)), HttpStatus.BAD_REQUEST); } } diff --git a/src/main/java/ru/ulstu/core/model/response/ResponseExtended.java b/src/main/java/ru/ulstu/core/model/response/ResponseExtended.java index 1829622..568e9b5 100644 --- a/src/main/java/ru/ulstu/core/model/response/ResponseExtended.java +++ b/src/main/java/ru/ulstu/core/model/response/ResponseExtended.java @@ -7,6 +7,6 @@ import ru.ulstu.core.model.ErrorConstants; public class ResponseExtended extends ResponseEntity { public ResponseExtended(ErrorConstants error, E errorData) { - super(new ControllerResponse(new ControllerResponseError(error, errorData)), HttpStatus.OK); + super(new ControllerResponse(new ControllerResponseError(error, errorData)), HttpStatus.BAD_REQUEST); } } diff --git a/src/main/java/ru/ulstu/user/controller/UserController.java b/src/main/java/ru/ulstu/user/controller/UserController.java index 6806d19..f674a23 100644 --- a/src/main/java/ru/ulstu/user/controller/UserController.java +++ b/src/main/java/ru/ulstu/user/controller/UserController.java @@ -19,6 +19,7 @@ import ru.ulstu.odin.controller.OdinController; import ru.ulstu.odin.model.OdinMetadata; import ru.ulstu.odin.model.OdinVoid; import ru.ulstu.odin.service.OdinService; +import ru.ulstu.user.model.User; import ru.ulstu.user.model.UserDto; import ru.ulstu.user.model.UserListDto; import ru.ulstu.user.model.UserResetPasswordDto; @@ -28,8 +29,12 @@ import ru.ulstu.user.model.UserSessionListDto; import ru.ulstu.user.service.UserService; import ru.ulstu.user.service.UserSessionService; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpSession; import javax.validation.Valid; +import java.util.Map; + import static ru.ulstu.user.controller.UserController.URL; @RestController @@ -141,13 +146,6 @@ public class UserController extends OdinController { return new Response<>(userService.activateUser(activationKey)); } - // TODO: add page for user password change (user-profile) - @PostMapping("/change-password") - public Response changePassword(@Valid @RequestBody UserDto userDto) { - log.debug("REST: UserController.changePassword( {} )", userDto.getLogin()); - return new Response<>(userService.changeUserPassword(userDto)); - } - @PostMapping(PASSWORD_RESET_REQUEST_URL) public Response requestPasswordReset(@RequestParam("email") String email) { log.debug("REST: UserController.requestPasswordReset( {} )", email); @@ -160,4 +158,12 @@ public class UserController extends OdinController { log.debug("REST: UserController.requestPasswordReset( {} )", key); return new Response<>(userService.completeUserPasswordReset(key, userResetPasswordDto)); } + + @PostMapping("/changePassword") + public void changePassword(@RequestBody Map payload, HttpServletRequest request) { + HttpSession session = request.getSession(false); + final String sessionId = session.getAttribute(Constants.SESSION_ID_ATTR).toString(); + User user = userSessionService.getUserBySessionId(sessionId); + userService.changeUserPassword(user, payload); + } } diff --git a/src/main/java/ru/ulstu/user/controller/UserMvcController.java b/src/main/java/ru/ulstu/user/controller/UserMvcController.java index c35dd79..29123e9 100644 --- a/src/main/java/ru/ulstu/user/controller/UserMvcController.java +++ b/src/main/java/ru/ulstu/user/controller/UserMvcController.java @@ -3,9 +3,7 @@ package ru.ulstu.user.controller; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Controller; -import org.springframework.ui.Model; import org.springframework.ui.ModelMap; -import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; @@ -37,12 +35,6 @@ public class UserMvcController extends OdinController { this.userSessionService = userSessionService; } - @ExceptionHandler(Exception.class) - public String errorHandler(Model model, Exception exception) { - model.addAttribute("error", exception.getMessage()); - return "/error/error"; - } - @GetMapping("/profile") public void getUserProfile(ModelMap modelMap, HttpServletRequest request) { HttpSession session = request.getSession(false); diff --git a/src/main/java/ru/ulstu/user/error/UserPasswordsNotValidOrNotMatchException.java b/src/main/java/ru/ulstu/user/error/UserPasswordsNotValidOrNotMatchException.java index 088f999..3edc1fa 100644 --- a/src/main/java/ru/ulstu/user/error/UserPasswordsNotValidOrNotMatchException.java +++ b/src/main/java/ru/ulstu/user/error/UserPasswordsNotValidOrNotMatchException.java @@ -1,6 +1,7 @@ package ru.ulstu.user.error; public class UserPasswordsNotValidOrNotMatchException extends RuntimeException { - public UserPasswordsNotValidOrNotMatchException() { + public UserPasswordsNotValidOrNotMatchException(String message) { + super(message); } } diff --git a/src/main/java/ru/ulstu/user/service/MailService.java b/src/main/java/ru/ulstu/user/service/MailService.java index 59d7e51..9c71c10 100644 --- a/src/main/java/ru/ulstu/user/service/MailService.java +++ b/src/main/java/ru/ulstu/user/service/MailService.java @@ -114,4 +114,10 @@ public class MailService { public void sendInviteMail(Map variables, String email) throws MessagingException { sendEmailFromTemplate(variables, "userInviteEmail", Constants.MAIL_INVITE, email); } + + @Async + public void sendChangePasswordMail(User user) { + sendEmailFromTemplate(user, "passwordChangeEmail", Constants.MAIL_CHANGE_PASSWORD); + + } } diff --git a/src/main/java/ru/ulstu/user/service/UserService.java b/src/main/java/ru/ulstu/user/service/UserService.java index 78f9d66..d82d564 100644 --- a/src/main/java/ru/ulstu/user/service/UserService.java +++ b/src/main/java/ru/ulstu/user/service/UserService.java @@ -128,7 +128,7 @@ public class UserService implements UserDetailsService { throw new UserEmailExistsException(userDto.getEmail()); } if (!userDto.isPasswordsValid()) { - throw new UserPasswordsNotValidOrNotMatchException(); + throw new UserPasswordsNotValidOrNotMatchException(""); } User user = userMapper.userDtoToUserEntity(userDto); user.setActivated(false); @@ -198,10 +198,10 @@ public class UserService implements UserDetailsService { : roles); if (!StringUtils.isEmpty(userDto.getOldPassword())) { if (!userDto.isPasswordsValid() || !userDto.isOldPasswordValid()) { - throw new UserPasswordsNotValidOrNotMatchException(); + throw new UserPasswordsNotValidOrNotMatchException(""); } if (!passwordEncoder.matches(userDto.getOldPassword(), user.getPassword())) { - throw new UserPasswordsNotValidOrNotMatchException(); + throw new UserPasswordsNotValidOrNotMatchException(""); } user.setPassword(passwordEncoder.encode(userDto.getPassword())); log.debug("Changed password for User: {}", user.getLogin()); @@ -221,24 +221,18 @@ public class UserService implements UserDetailsService { return userMapper.userEntityToUserDto(user); } - public UserDto changeUserPassword(UserDto userDto) { - if (userDto.getId() == null) { - throw new EntityIdIsNullException(); - } - if (!userDto.isPasswordsValid() || !userDto.isOldPasswordValid()) { - throw new UserPasswordsNotValidOrNotMatchException(); - } - final String login = UserUtils.getCurrentUserLogin(); - final User user = userRepository.findOneByLoginIgnoreCase(login); - if (user == null) { - throw new UserNotFoundException(login); + public void changeUserPassword(User user, Map payload) { + if (!payload.get("password").equals(payload.get("confirmPassword"))) { + throw new UserPasswordsNotValidOrNotMatchException(""); } - if (!passwordEncoder.matches(userDto.getOldPassword(), user.getPassword())) { - throw new UserPasswordsNotValidOrNotMatchException(); + if (!passwordEncoder.matches(payload.get("oldPassword"), user.getPassword())) { + throw new UserPasswordsNotValidOrNotMatchException("Старый пароль введен неправильно"); } - user.setPassword(passwordEncoder.encode(userDto.getPassword())); + user.setPassword(passwordEncoder.encode(payload.get("password"))); log.debug("Changed password for User: {}", user.getLogin()); - return userMapper.userEntityToUserDto(userRepository.save(user)); + userRepository.save(user); + + mailService.sendChangePasswordMail(user); } public boolean requestUserPasswordReset(String email) { @@ -259,7 +253,7 @@ public class UserService implements UserDetailsService { public boolean completeUserPasswordReset(String key, UserResetPasswordDto userResetPasswordDto) { if (!userResetPasswordDto.isPasswordsValid()) { - throw new UserPasswordsNotValidOrNotMatchException(); + throw new UserPasswordsNotValidOrNotMatchException(""); } User user = userRepository.findOneByResetKey(key); if (user == null) { diff --git a/src/main/resources/mail_templates/passwordChangeEmail.html b/src/main/resources/mail_templates/passwordChangeEmail.html new file mode 100644 index 0000000..ec15a36 --- /dev/null +++ b/src/main/resources/mail_templates/passwordChangeEmail.html @@ -0,0 +1,21 @@ + + + + Password reset + + + + +

+ Dear Ivan Ivanov +

+

+ Your password has been changed. +

+

+ Regards, +
+ Balance Team. +

+ + diff --git a/src/main/resources/public/js/users.js b/src/main/resources/public/js/users.js new file mode 100644 index 0000000..fee4f70 --- /dev/null +++ b/src/main/resources/public/js/users.js @@ -0,0 +1,33 @@ +function changePassword() { + oldPassword = document.getElementById("oldPassword").value + password = document.getElementById("password").value + confirmPassword = document.getElementById("confirmPassword").value + + if ([oldPassword.length, password.length, confirmPassword.length].includes(0)) { + alert("Заполните все поля"); + return; + } + + if (password != confirmPassword) { + alert("Повторный пароль введен неверно"); + return; + } + + $.ajax({ + url:"/api/1.0/users/changePassword", + contentType: "application/json; charset=utf-8", + data: JSON.stringify({ + "oldPassword": document.getElementById("oldPassword").value, + "password": document.getElementById("password").value, + "confirmPassword": document.getElementById("confirmPassword").value, + }), + method: "POST", + success: function() { + document.getElementById("closeModalPassword").click(); + alert("Пароль был обновлен"); + }, + error: function(errorData) { + alert(errorData.responseJSON.error.message) + } + }) +} \ No newline at end of file diff --git a/src/main/resources/templates/default.html b/src/main/resources/templates/default.html index 0c92865..32939e7 100644 --- a/src/main/resources/templates/default.html +++ b/src/main/resources/templates/default.html @@ -70,6 +70,7 @@ Личный кабинет Выход Пригласить + Сменить пароль @@ -77,6 +78,7 @@
+