diff --git a/continew-admin-common/src/main/java/top/charles7c/cnadmin/common/consts/RegExpConstants.java b/continew-admin-common/src/main/java/top/charles7c/cnadmin/common/consts/RegExpConstants.java new file mode 100644 index 00000000..a1e50f2d --- /dev/null +++ b/continew-admin-common/src/main/java/top/charles7c/cnadmin/common/consts/RegExpConstants.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package top.charles7c.cnadmin.common.consts; + +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + +/** + * @author Charles7c + * @since 2023/1/10 20:06 + */ +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public class RegExpConstants { + + /** + * 密码正则(必须包含字母和数字的组合,可以使用特殊字符,长度在6-32之间) + */ + public static final String PASSWORD = "^(?=.*\\d)(?=.*[a-z]).{6,32}$"; +} diff --git a/continew-admin-common/src/main/java/top/charles7c/cnadmin/common/util/SecureUtils.java b/continew-admin-common/src/main/java/top/charles7c/cnadmin/common/util/SecureUtils.java index e38f9605..14cdd208 100644 --- a/continew-admin-common/src/main/java/top/charles7c/cnadmin/common/util/SecureUtils.java +++ b/continew-admin-common/src/main/java/top/charles7c/cnadmin/common/util/SecureUtils.java @@ -23,6 +23,9 @@ import cn.hutool.core.codec.Base64; import cn.hutool.crypto.SecureUtil; import cn.hutool.crypto.asymmetric.KeyType; +import top.charles7c.cnadmin.common.config.properties.RsaProperties; +import top.charles7c.cnadmin.common.util.validate.ValidationUtils; + /** * 加密/解密工具类 * @@ -45,6 +48,19 @@ public class SecureUtils { return Base64.encode(SecureUtil.rsa(null, publicKey).encrypt(data, KeyType.PublicKey)); } + /** + * 私钥解密 + * + * @param data + * 要解密的内容(Base64 加密过) + * @return 解密后的内容 + */ + public static String decryptByRsaPrivateKey(String data) { + String privateKey = RsaProperties.PRIVATE_KEY; + ValidationUtils.exIfBlank(privateKey, "请配置 RSA 私钥"); + return decryptByRsaPrivateKey(data, privateKey); + } + /** * 私钥解密 * diff --git a/continew-admin-system/src/main/java/top/charles7c/cnadmin/auth/model/request/LoginRequest.java b/continew-admin-system/src/main/java/top/charles7c/cnadmin/auth/model/request/LoginRequest.java index 8633bebf..e8093a22 100644 --- a/continew-admin-system/src/main/java/top/charles7c/cnadmin/auth/model/request/LoginRequest.java +++ b/continew-admin-system/src/main/java/top/charles7c/cnadmin/auth/model/request/LoginRequest.java @@ -44,9 +44,9 @@ public class LoginRequest implements Serializable { private String username; /** - * 密码 + * 密码(加密后) */ - @Schema(description = "密码") + @Schema(description = "密码(加密后)") @NotBlank(message = "密码不能为空") private String password; diff --git a/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/model/request/UpdatePasswordRequest.java b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/model/request/UpdatePasswordRequest.java new file mode 100644 index 00000000..fb262ba0 --- /dev/null +++ b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/model/request/UpdatePasswordRequest.java @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package top.charles7c.cnadmin.system.model.request; + +import java.io.Serializable; + +import javax.validation.constraints.NotBlank; + +import lombok.Data; + +import io.swagger.v3.oas.annotations.media.Schema; + +/** + * 修改密码信息 + * + * @author Charles7c + * @since 2023/1/9 23:28 + */ +@Data +@Schema(description = "修改密码信息") +public class UpdatePasswordRequest implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 当前密码(加密后) + */ + @Schema(description = "当前密码(加密后)") + @NotBlank(message = "当前密码不能为空") + private String oldPassword; + + /** + * 新密码(加密后) + */ + @Schema(description = "新密码(加密后)") + @NotBlank(message = "新密码不能为空") + private String newPassword; +} diff --git a/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/service/UserService.java b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/service/UserService.java index a95289e9..ce4afa9c 100644 --- a/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/service/UserService.java +++ b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/service/UserService.java @@ -55,4 +55,16 @@ public interface UserService { * 用户信息 */ void update(SysUser user); + + /** + * 修改密码 + * + * @param oldPassword + * 当前密码 + * @param newPassword + * 新密码 + * @param userId + * 用户 ID + */ + void updatePassword(String oldPassword, String newPassword, Long userId); } diff --git a/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/service/impl/UserServiceImpl.java b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/service/impl/UserServiceImpl.java index 70fc5265..5aabfca5 100644 --- a/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/service/impl/UserServiceImpl.java +++ b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/service/impl/UserServiceImpl.java @@ -17,6 +17,7 @@ package top.charles7c.cnadmin.system.service.impl; import java.io.File; +import java.time.LocalDateTime; import lombok.RequiredArgsConstructor; @@ -34,8 +35,10 @@ import cn.hutool.core.util.StrUtil; import top.charles7c.cnadmin.common.config.properties.LocalStorageProperties; import top.charles7c.cnadmin.common.model.dto.LoginUser; import top.charles7c.cnadmin.common.util.FileUtils; +import top.charles7c.cnadmin.common.util.SecureUtils; import top.charles7c.cnadmin.common.util.helper.LoginHelper; import top.charles7c.cnadmin.common.util.validate.CheckUtils; +import top.charles7c.cnadmin.common.util.validate.ValidationUtils; import top.charles7c.cnadmin.system.mapper.UserMapper; import top.charles7c.cnadmin.system.model.entity.SysUser; import top.charles7c.cnadmin.system.service.UserService; @@ -91,9 +94,43 @@ public class UserServiceImpl implements UserService { userMapper.updateById(user); // 更新登录用户信息 - SysUser sysUser = userMapper.selectById(user.getUserId()); + SysUser sysUser = this.getById(user.getUserId()); LoginUser loginUser = LoginHelper.getLoginUser(); BeanUtil.copyProperties(sysUser, loginUser); LoginHelper.updateLoginUser(loginUser); } + + @Override + @Transactional(rollbackFor = Exception.class) + public void updatePassword(String oldPassword, String newPassword, Long userId) { + SysUser sysUser = this.getById(userId); + ValidationUtils.exIfNotEqual(sysUser.getPassword(), SecureUtils.md5Salt(oldPassword, userId.toString()), + "当前密码错误"); + + // 更新密码和密码重置时间 + LocalDateTime now = LocalDateTime.now(); + userMapper.update(null, + new LambdaUpdateWrapper() + .set(SysUser::getPassword, SecureUtils.md5Salt(newPassword, userId.toString())) + .set(SysUser::getPwdResetTime, now).eq(SysUser::getUserId, userId)); + + // 更新登录用户信息 + LoginUser loginUser = LoginHelper.getLoginUser(); + loginUser.setPwdResetTime(now); + LoginHelper.updateLoginUser(loginUser); + } + + /** + * 根据 ID 查询 + * + * @param userId + * 用户 ID + * @return 用户信息 + */ + private SysUser getById(Long userId) { + ValidationUtils.exIfNull(userId, "用户不存在"); + SysUser sysUser = userMapper.selectById(userId); + ValidationUtils.exIfNull(sysUser, String.format("ID为 [%s] 的用户已不存在", userId)); + return sysUser; + } } diff --git a/continew-admin-ui/src/api/system/user-center.ts b/continew-admin-ui/src/api/system/user-center.ts index 5bb69871..4e68ddf9 100644 --- a/continew-admin-ui/src/api/system/user-center.ts +++ b/continew-admin-ui/src/api/system/user-center.ts @@ -19,4 +19,12 @@ export interface UpdateBasicInfoReq { } export function updateBasicInfo(req: UpdateBasicInfoReq) { return axios.patch('/system/user/center/basic/info', req); +} + +export interface UpdatePasswordReq { + oldPassword: string; + newPassword: string; +} +export function updatePassword(req: UpdatePasswordReq) { + return axios.patch('/system/user/center/password', req); } \ No newline at end of file diff --git a/continew-admin-ui/src/views/login/components/login-form.vue b/continew-admin-ui/src/views/login/components/login-form.vue index f43fa305..9ed6a03c 100644 --- a/continew-admin-ui/src/views/login/components/login-form.vue +++ b/continew-admin-ui/src/views/login/components/login-form.vue @@ -105,9 +105,9 @@ const loginConfig = useStorage('login-config', { rememberMe: true, username: 'admin', // 演示默认值 - password: '123456', // 演示默认值 + password: 'admin123', // 演示默认值 // username: !debug ? '' : 'admin', // 演示默认值 - // password: !debug ? '' : '123456', // 演示默认值 + // password: !debug ? '' : 'admin123', // 演示默认值 }); const loginForm = reactive({ diff --git a/continew-admin-ui/src/views/system/user/center/components/basic-information.vue b/continew-admin-ui/src/views/system/user/center/components/basic-information.vue index 3d1ba656..81881dc2 100644 --- a/continew-admin-ui/src/views/system/user/center/components/basic-information.vue +++ b/continew-admin-ui/src/views/system/user/center/components/basic-information.vue @@ -19,6 +19,7 @@ @@ -35,6 +36,7 @@ diff --git a/continew-admin-ui/src/views/system/user/center/components/security-settings.vue b/continew-admin-ui/src/views/system/user/center/components/security-settings.vue index 0babbb9c..39a3173e 100644 --- a/continew-admin-ui/src/views/system/user/center/components/security-settings.vue +++ b/continew-admin-ui/src/views/system/user/center/components/security-settings.vue @@ -1,10 +1,85 @@