diff --git a/core/backend/src/main/java/io/dataease/auth/entity/SysUserEntity.java b/core/backend/src/main/java/io/dataease/auth/entity/SysUserEntity.java index 2022ee6150..e5590981e5 100644 --- a/core/backend/src/main/java/io/dataease/auth/entity/SysUserEntity.java +++ b/core/backend/src/main/java/io/dataease/auth/entity/SysUserEntity.java @@ -44,4 +44,6 @@ public class SysUserEntity implements Serializable { @ApiModelProperty(hidden = true) private Integer from; + @ApiModelProperty(hidden = true) + private Long pwdResetTime; } diff --git a/core/backend/src/main/java/io/dataease/auth/server/AuthServer.java b/core/backend/src/main/java/io/dataease/auth/server/AuthServer.java index 2f594c6039..90ff442385 100644 --- a/core/backend/src/main/java/io/dataease/auth/server/AuthServer.java +++ b/core/backend/src/main/java/io/dataease/auth/server/AuthServer.java @@ -111,7 +111,7 @@ public class AuthServer implements AuthApi { String pwd = RsaUtil.decryptByPrivateKey(RsaProperties.privateKey, loginDto.getPassword()); // 增加ldap登录方式 - Integer loginType = loginDto.getLoginType(); + int loginType = loginDto.getLoginType(); boolean isSupportLdap = authUserService.supportLdap(); if (loginType == 1 && isSupportLdap) { AccountLockStatus accountLockStatus = authUserService.lockStatus(username, 1); @@ -195,11 +195,19 @@ public class AuthServer implements AuthApi { result.put("passwordModified", false); result.put("defaultPwd", "dataease"); } - if (!user.getIsAdmin() && user.getPassword().equals(CodingUtil.md5(DEFAULT_PWD))) { result.put("passwordModified", false); result.put("defaultPwd", DEFAULT_PWD); } + if (user.getIsAdmin()) { + result.put("validityPeriod", -1); + } else { + Integer validityPeriod = systemParameterService.pwdValidityPeriod(user.getPwdResetTime()); + if (validityPeriod.equals(0)) { + DataEaseException.throwException("pwdValidityPeriod"); + } + result.put("validityPeriod", validityPeriod); + } } Long expireTime = System.currentTimeMillis() + JWTUtils.getExpireTime(); TokenInfo tokenInfo = TokenInfo.builder().userId(user.getUserId()).username(username).build(); diff --git a/core/backend/src/main/java/io/dataease/commons/constants/ParamConstants.java b/core/backend/src/main/java/io/dataease/commons/constants/ParamConstants.java index e242b1bc14..5889f54a86 100644 --- a/core/backend/src/main/java/io/dataease/commons/constants/ParamConstants.java +++ b/core/backend/src/main/java/io/dataease/commons/constants/ParamConstants.java @@ -126,6 +126,8 @@ public interface ParamConstants { LOGIN_LIMIT_RELIEVETIMES("loginlimit.relieveTimes"), LOGIN_LIMIT_OPEN("loginlimit.open"), + LOGIN_LIMIT_OPEN_MODIFY_PWD("loginlimit.openModifyPwd"), + LOGIN_LIMIT_PWD_CYCLE("loginlimit.pwdCycle"), LOCKED_EMAIL("loginlimit.lockedEmail"), SCAN_CREATE_USER("loginlimit.scanCreateUser"), diff --git a/core/backend/src/main/java/io/dataease/ext/AuthMapper.xml b/core/backend/src/main/java/io/dataease/ext/AuthMapper.xml index 9710597aa6..4578aafe29 100644 --- a/core/backend/src/main/java/io/dataease/ext/AuthMapper.xml +++ b/core/backend/src/main/java/io/dataease/ext/AuthMapper.xml @@ -14,6 +14,7 @@ + @@ -48,7 +49,11 @@ password, enabled, email, - phone, language, is_admin, `from` + pwd_reset_time, + phone, + language, + is_admin, + `from` from sys_user where username = #{username} @@ -61,9 +66,13 @@ password, enabled, email, - phone, language, is_admin, `from` + phone, + language, + is_admin, + `from` from sys_user a - where username = #{username} and a.from = 1 + where username = #{username} + and a.from = 1 @@ -75,9 +84,13 @@ password, enabled, email, - phone, language, is_admin, `from` + phone, + language, + is_admin, + `from` from sys_user a - where username = #{username} and a.from = 3 + where username = #{username} + and a.from = 3 @@ -161,12 +179,14 @@ password, enabled, email, - phone, language, is_admin, `from` - from - sys_user_assist a - left join - sys_user u - on u.user_id = a.user_id + phone, + language, + is_admin, + `from` + from sys_user_assist a + left join + sys_user u + on u.user_id = a.user_id where a.dingtalk_id = #{dingtalkId} @@ -178,12 +198,14 @@ password, enabled, email, - phone, language, is_admin, `from` - from - sys_user_assist a - left join - sys_user u - on u.user_id = a.user_id + phone, + language, + is_admin, + `from` + from sys_user_assist a + left join + sys_user u + on u.user_id = a.user_id where a.lark_id = #{larkId} @@ -195,12 +217,14 @@ password, enabled, email, - phone, language, is_admin, `from` - from - sys_user_assist a - left join - sys_user u - on u.user_id = a.user_id + phone, + language, + is_admin, + `from` + from sys_user_assist a + left join + sys_user u + on u.user_id = a.user_id where a.larksuite_id = #{larksuiteId} diff --git a/core/backend/src/main/java/io/dataease/service/sys/SysUserService.java b/core/backend/src/main/java/io/dataease/service/sys/SysUserService.java index 6a113e975c..3c5dd0cf38 100644 --- a/core/backend/src/main/java/io/dataease/service/sys/SysUserService.java +++ b/core/backend/src/main/java/io/dataease/service/sys/SysUserService.java @@ -4,7 +4,6 @@ import io.dataease.auth.api.dto.CurrentUserDto; import io.dataease.auth.service.AuthUserService; import io.dataease.auth.service.ExtAuthService; import io.dataease.commons.constants.AuthConstants; - import io.dataease.commons.utils.AuthUtils; import io.dataease.commons.utils.BeanUtils; import io.dataease.commons.utils.CodingUtil; @@ -101,6 +100,7 @@ public class SysUserService { if (StringUtils.isEmpty(user.getLanguage())) { user.setLanguage("zh_CN"); } + user.setPwdResetTime(now); int insert = sysUserMapper.insert(user); SysUser dbUser = findOne(user); Long userId = dbUser.getUserId(); @@ -123,6 +123,7 @@ public class SysUserService { sysUser.setNickName(ssoUserInfo.getNickName()); sysUser.setEmail(ssoUserInfo.getEmail()); sysUser.setPassword(CodingUtil.md5(DEFAULT_PWD)); + sysUser.setPwdResetTime(System.currentTimeMillis()); sysUser.setCreateTime(now); sysUser.setUpdateTime(now); sysUser.setEnabled(1L); @@ -149,6 +150,7 @@ public class SysUserService { sysUser.setNickName(userMap.get("name").toString()); sysUser.setEmail(email); sysUser.setPassword(CodingUtil.md5(DEFAULT_PWD)); + sysUser.setPwdResetTime(System.currentTimeMillis()); sysUser.setCreateTime(now); sysUser.setUpdateTime(now); @@ -172,6 +174,7 @@ public class SysUserService { sysUser.setNickName(dingUserEntity.getName()); sysUser.setEmail(email); sysUser.setPassword(CodingUtil.md5(DEFAULT_PWD)); + sysUser.setPwdResetTime(System.currentTimeMillis()); sysUser.setCreateTime(now); sysUser.setUpdateTime(now); @@ -194,6 +197,7 @@ public class SysUserService { sysUser.setNickName(larkUserInfo.getName()); sysUser.setEmail(email); sysUser.setPassword(CodingUtil.md5(DEFAULT_PWD)); + sysUser.setPwdResetTime(System.currentTimeMillis()); sysUser.setCreateTime(now); sysUser.setUpdateTime(now); @@ -216,6 +220,7 @@ public class SysUserService { sysUser.setNickName(larkUserInfo.getName()); sysUser.setEmail(email); sysUser.setPassword(CodingUtil.md5(DEFAULT_PWD)); + sysUser.setPwdResetTime(System.currentTimeMillis()); sysUser.setCreateTime(now); sysUser.setUpdateTime(now); @@ -236,6 +241,7 @@ public class SysUserService { sysUser.setUsername(name); sysUser.setNickName(name); sysUser.setEmail(email); + sysUser.setPwdResetTime(System.currentTimeMillis()); sysUser.setPassword(CodingUtil.md5(DEFAULT_PWD)); sysUser.setCreateTime(now); sysUser.setUpdateTime(now); @@ -267,6 +273,7 @@ public class SysUserService { sysUser.setUsername(user.getUsername()); sysUser.setNickName(user.getNickname()); sysUser.setDeptId(request.getDeptId()); + sysUser.setPwdResetTime(System.currentTimeMillis()); sysUser.setPassword(CodingUtil.md5(DEFAULT_PWD)); sysUser.setCreateTime(now); sysUser.setUpdateTime(now); @@ -403,6 +410,7 @@ public class SysUserService { DataEaseException.throwException(Translator.get(msg)); } sysUser.setPassword(CodingUtil.md5(request.getNewPassword())); + sysUser.setPwdResetTime(System.currentTimeMillis()); return sysUserMapper.updateByPrimaryKeySelective(sysUser); } @@ -410,6 +418,7 @@ public class SysUserService { public int adminUpdatePwd(SysUserPwdRequest request) { SysUser sysUser = new SysUser(); sysUser.setUserId(request.getUserId()); + sysUser.setPwdResetTime(System.currentTimeMillis()); sysUser.setPassword(CodingUtil.md5(new String(java.util.Base64.getDecoder().decode(request.getNewPassword())))); return sysUserMapper.updateByPrimaryKeySelective(sysUser); } diff --git a/core/backend/src/main/java/io/dataease/service/system/SystemParameterService.java b/core/backend/src/main/java/io/dataease/service/system/SystemParameterService.java index 4e339c3224..c13ae34151 100644 --- a/core/backend/src/main/java/io/dataease/service/system/SystemParameterService.java +++ b/core/backend/src/main/java/io/dataease/service/system/SystemParameterService.java @@ -1,7 +1,6 @@ package io.dataease.service.system; import io.dataease.commons.constants.ParamConstants; -; import io.dataease.commons.utils.BeanUtils; import io.dataease.commons.utils.EncryptUtils; import io.dataease.controller.sys.response.BasicInfo; @@ -36,6 +35,9 @@ import java.io.InputStream; import java.util.*; import java.util.concurrent.atomic.AtomicReference; +import static io.dataease.commons.constants.ParamConstants.BASIC.LOGIN_LIMIT_OPEN_MODIFY_PWD; +import static io.dataease.commons.constants.ParamConstants.BASIC.LOGIN_LIMIT_PWD_CYCLE; + @Service @Transactional(rollbackFor = Exception.class) public class SystemParameterService { @@ -70,7 +72,7 @@ public class SystemParameterService { BasicInfo result = new BasicInfo(); result.setOpenHomePage("true"); Map beansOfType = SpringContextUtil.getApplicationContext().getBeansOfType((LoginLimitXpackService.class)); - Boolean loginLimitPluginLoaded = beansOfType.keySet().size() > 0; + boolean loginLimitPluginLoaded = beansOfType.keySet().size() > 0; if (!CollectionUtils.isEmpty(paramList)) { for (SystemParameter param : paramList) { if (StringUtils.equals(param.getParamKey(), ParamConstants.BASIC.FRONT_TIME_OUT.getValue())) { @@ -132,6 +134,16 @@ public class SystemParameterService { boolean open = StringUtils.equals("true", param.getParamValue()); result.setOpen(open ? "true" : "false"); } + if (StringUtils.equals(param.getParamKey(), LOGIN_LIMIT_OPEN_MODIFY_PWD.getValue())) { + boolean open = StringUtils.equals("true", param.getParamValue()); + result.setOpenModifyPwd(open ? "true" : "false"); + } + if (StringUtils.equals(param.getParamKey(), ParamConstants.BASIC.LOGIN_LIMIT_PWD_CYCLE.getValue())) { + String paramValue = param.getParamValue(); + if (StringUtils.isNotBlank(paramValue)) { + result.setPwdCycle(paramValue); + } + } if (StringUtils.equals(param.getParamKey(), ParamConstants.BASIC.LOCKED_EMAIL.getValue())) { boolean open = StringUtils.equals("true", param.getParamValue()); result.setLockedEmail(open ? "true" : "false"); @@ -286,6 +298,38 @@ public class SystemParameterService { return param.getParamValue(); } + public Integer pwdValidityPeriod(Long pwdTime) { + if (ObjectUtils.isEmpty(pwdTime)) { + return -1; + } + Map beansOfType = SpringContextUtil.getApplicationContext().getBeansOfType((LoginLimitXpackService.class)); + boolean loginLimitPluginLoaded = beansOfType.keySet().size() > 0; + if (!loginLimitPluginLoaded) return -1; + String value = getValue(LOGIN_LIMIT_OPEN_MODIFY_PWD.getValue()); + if (StringUtils.isNotBlank(value) && StringUtils.equals("true", value)) { + long dayTime = 24 * 3600L * 1000L; + String pwdCycle = getValue(LOGIN_LIMIT_PWD_CYCLE.getValue()); + Long expireCycle = null; + if (StringUtils.isBlank(pwdCycle) || StringUtils.equals("1", pwdCycle)) { + expireCycle = 90L * dayTime; + } else if (StringUtils.equals("2", pwdCycle)) { + expireCycle = 180L * dayTime; + } else { + expireCycle = 365L * dayTime; + } + long now = System.currentTimeMillis(); + long validityPeriod = pwdTime + expireCycle - now; + if (validityPeriod < 0L) return 0; + long validityDays = validityPeriod / dayTime; + if (validityPeriod % dayTime != 0) { + validityDays++; + } + return (int) validityDays; + } + return -1; + } + + public void disabledLockedEmail() { SystemParameter param = systemParameterMapper.selectByPrimaryKey(ParamConstants.BASIC.LOCKED_EMAIL.getValue()); if (ObjectUtils.isNotEmpty(param)) { diff --git a/core/backend/src/main/resources/db/migration/V64__1.18.19_export_task.sql b/core/backend/src/main/resources/db/migration/V64__1.18.19_export_task.sql index d48bbabb7e..92c171d2f0 100644 --- a/core/backend/src/main/resources/db/migration/V64__1.18.19_export_task.sql +++ b/core/backend/src/main/resources/db/migration/V64__1.18.19_export_task.sql @@ -1,16 +1,24 @@ DROP TABLE IF EXISTS `export_task`; -CREATE TABLE `export_task` ( - `id` varchar(255) NOT NULL, - `user_id` bigint(20) NOT NULL , - `file_name` varchar(2048) DEFAULT NULL, - `file_size` DOUBLE DEFAULT NULL, - `file_size_unit` varchar(255) DEFAULT NULL, - `export_from` varchar(255) DEFAULT NULL, - `export_status` varchar(255) DEFAULT NULL, - `export_from_type` varchar(255) DEFAULT NULL, - `export_time` bigint(20) DEFAULT NULL, - `export_pogress` varchar(255) DEFAULT NULL, - `export_machine_name` varchar(512) DEFAULT NULL, - `params` longtext NOT NULL COMMENT '过滤参数', - PRIMARY KEY (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_general_ci; \ No newline at end of file +CREATE TABLE `export_task` +( + `id` varchar(255) NOT NULL, + `user_id` bigint(20) NOT NULL, + `file_name` varchar(2048) DEFAULT NULL, + `file_size` DOUBLE DEFAULT NULL, + `file_size_unit` varchar(255) DEFAULT NULL, + `export_from` varchar(255) DEFAULT NULL, + `export_status` varchar(255) DEFAULT NULL, + `export_from_type` varchar(255) DEFAULT NULL, + `export_time` bigint(20) DEFAULT NULL, + `export_pogress` varchar(255) DEFAULT NULL, + `export_machine_name` varchar(512) DEFAULT NULL, + `params` longtext NOT NULL COMMENT '过滤参数', + PRIMARY KEY (`id`) +) ENGINE = InnoDB + DEFAULT CHARSET = utf8mb4 + COLLATE utf8mb4_general_ci; + + +update `sys_user` +set `pwd_reset_time` = `update_time` +where `pwd_reset_time` IS NULL; \ No newline at end of file diff --git a/core/frontend/src/store/modules/user.js b/core/frontend/src/store/modules/user.js index 9667c7521a..7380ecf67b 100644 --- a/core/frontend/src/store/modules/user.js +++ b/core/frontend/src/store/modules/user.js @@ -20,7 +20,9 @@ const getDefaultState = () => { permissions: [], language: getLanguage(), uiInfo: null, - linkToken: null + linkToken: null, + validityPeriod: -1, + loginMsg: null } } @@ -69,6 +71,9 @@ const mutations = { }, SET_PASSWORD_MODIFIED: (state, passwordModified) => { state.passwordModified = passwordModified + }, + SET_VALIDITY_PERIOD: (state, validityPeriod) => { + state.validityPeriod = validityPeriod } } @@ -79,8 +84,15 @@ const actions = { return new Promise((resolve, reject) => { login({ username: username.trim(), password: password, loginType: loginType }).then(response => { const { data } = response - commit('SET_TOKEN', data.token) commit('SET_LOGIN_MSG', null) + if (data.validityPeriod === 0) { + commit('SET_LOGIN_MSG', '密码已过期,请联系管理员进行密码重置!') + reject(null) + return + } else if (data.validityPeriod > 0 && data.validityPeriod < 8) { + commit('SET_LOGIN_MSG', `密码将于${data.validityPeriod}天后过期,为了不影响正常使用,请及时进行修改!`) + } + commit('SET_TOKEN', data.token) setToken(data.token) setTokenExp(data.expireTime) let passwordModified = true @@ -92,8 +104,10 @@ const actions = { } commit('SET_PASSWORD_MODIFIED', passwordModified) localStorage.setItem('passwordModified', passwordModified) + commit('SET_VALIDITY_PERIOD', data.validityPeriod) resolve() }).catch(error => { + error?.response?.data?.message?.startsWith('pwdValidityPeriod') && commit('SET_LOGIN_MSG', '密码已过期,请联系管理员进行密码重置!') reject(error) }) }) diff --git a/core/frontend/src/utils/request.js b/core/frontend/src/utils/request.js index 5bc5f02ba0..ffb4bb8e59 100644 --- a/core/frontend/src/utils/request.js +++ b/core/frontend/src/utils/request.js @@ -133,6 +133,9 @@ service.interceptors.response.use(response => { if (error.response) { checkAuth(error.response) msg = error.response.data.message || error.response.data + if (msg?.startsWith('pwdValidityPeriod')) { + config['hideMsg'] = true + } } else { msg = error.message } diff --git a/core/frontend/src/views/login/index.vue b/core/frontend/src/views/login/index.vue index 883ac0cc98..9d25943634 100644 --- a/core/frontend/src/views/login/index.vue +++ b/core/frontend/src/views/login/index.vue @@ -120,7 +120,10 @@ {{ uiInfo['ui.demo.tips'].paramValue }} - item < 4 || item > 6) || [] + }, + pwdPeriodWarn() { + return this.$store.state.user.validityPeriod > 0 && this.$store.state.user.validityPeriod < 8 } }, watch: { @@ -496,7 +501,11 @@ export default { loginType: this.loginForm.loginType } this.$store.dispatch('user/login', user).then(() => { - this.$router.push({ path: this.redirect || '/' }) + if (this.pwdPeriodWarn) { + this.showPwdPeriodMsg() + } else { + this.$router.push({ path: this.redirect || '/' }) + } this.loading = false }).catch((e) => { this.loading = false @@ -507,6 +516,11 @@ export default { } }) }, + showPwdPeriodMsg() { + setTimeout(() => { + this.$router.push({ path: this.redirect || '/' }) + }, 2000) + }, showMessage() { showMultiLoginMsg() }, @@ -649,6 +663,9 @@ export default { color: $--color-danger; text-align: center; } + .login-msg-warn { + color: $--color-warning !important; + } .login-image { background: url(../../assets/login-desc.png) no-repeat; diff --git a/core/frontend/src/views/system/sysParam/BasicSetting.vue b/core/frontend/src/views/system/sysParam/BasicSetting.vue index 7f1aa183bd..3d600294f2 100644 --- a/core/frontend/src/views/system/sysParam/BasicSetting.vue +++ b/core/frontend/src/views/system/sysParam/BasicSetting.vue @@ -388,6 +388,7 @@ export default { this.originLoginType = this.formInline.loginType } this.formInline.open = (this.formInline.open && this.formInline.open === 'true') + this.formInline.openModifyPwd = (this.formInline.openModifyPwd && this.formInline.openModifyPwd === 'true') this.formInline.lockedEmail = this.formInline?.lockedEmail === 'true' this.formInline.scanCreateUser = (this.formInline.scanCreateUser && this.formInline.scanCreateUser === 'true') @@ -501,6 +502,18 @@ export default { paramValue: this.formInline.multiLogin, type: 'text', sort: 3 + }, + { + paramKey: 'loginlimit.openModifyPwd', + paramValue: this.formInline.open, + type: 'text', + sort: 5 + }, + { + paramKey: 'loginlimit.pwdCycle', + paramValue: this.formInline.pwdCycle, + type: 'text', + sort: 6 } ] diff --git a/sdk/dataease-plugin-interface/src/main/java/io/dataease/plugins/xpack/loginlimit/dto/response/LoginLimitInfo.java b/sdk/dataease-plugin-interface/src/main/java/io/dataease/plugins/xpack/loginlimit/dto/response/LoginLimitInfo.java index 59344be9bb..681900a0bd 100644 --- a/sdk/dataease-plugin-interface/src/main/java/io/dataease/plugins/xpack/loginlimit/dto/response/LoginLimitInfo.java +++ b/sdk/dataease-plugin-interface/src/main/java/io/dataease/plugins/xpack/loginlimit/dto/response/LoginLimitInfo.java @@ -16,4 +16,8 @@ public class LoginLimitInfo { private String multiLogin; private String lockedEmail = "false"; + + private String openModifyPwd; + + private String pwdCycle = "1"; }