增加密码校验
This commit is contained in:
parent
a93308d5dd
commit
8521290ee4
|
|
@ -5,30 +5,33 @@
|
|||
* @returns {Boolean}
|
||||
*/
|
||||
export function isPathMatch(pattern, path) {
|
||||
const regexPattern = pattern.replace(/\//g, '\\/').replace(/\*\*/g, '.*').replace(/\*/g, '[^\\/]*')
|
||||
const regex = new RegExp(`^${regexPattern}$`)
|
||||
return regex.test(path)
|
||||
const regexPattern = pattern
|
||||
.replace(/\//g, '\\/')
|
||||
.replace(/\*\*/g, '.*')
|
||||
.replace(/\*/g, '[^\\/]*')
|
||||
const regex = new RegExp(`^${regexPattern}$`)
|
||||
return regex.test(path)
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断value字符串是否为空
|
||||
* 判断value字符串是否为空
|
||||
* @param {string} value
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
export function isEmpty(value) {
|
||||
if (value == null || value == "" || value == undefined || value == "undefined") {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
if (value == null || value == '' || value == undefined || value == 'undefined') {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断url是否是http或https
|
||||
* 判断url是否是http或https
|
||||
* @param {string} url
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
export function isHttp(url) {
|
||||
return url.indexOf('http://') !== -1 || url.indexOf('https://') !== -1
|
||||
return url.indexOf('http://') !== -1 || url.indexOf('https://') !== -1
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -37,7 +40,7 @@ export function isHttp(url) {
|
|||
* @returns {Boolean}
|
||||
*/
|
||||
export function isExternal(path) {
|
||||
return /^(https?:|mailto:|tel:)/.test(path)
|
||||
return /^(https?:|mailto:|tel:)/.test(path)
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -45,8 +48,8 @@ export function isExternal(path) {
|
|||
* @returns {Boolean}
|
||||
*/
|
||||
export function validUsername(str) {
|
||||
const valid_map = ['admin', 'editor']
|
||||
return valid_map.indexOf(str.trim()) >= 0
|
||||
const valid_map = ['admin', 'editor']
|
||||
return valid_map.indexOf(str.trim()) >= 0
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -54,8 +57,9 @@ export function validUsername(str) {
|
|||
* @returns {Boolean}
|
||||
*/
|
||||
export function validURL(url) {
|
||||
const reg = /^(https?|ftp):\/\/([a-zA-Z0-9.-]+(:[a-zA-Z0-9.&%$-]+)*@)*((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(:[0-9]+)*(\/($|[a-zA-Z0-9.,?'\\+&%$#=~_-]+))*$/
|
||||
return reg.test(url)
|
||||
const reg =
|
||||
/^(https?|ftp):\/\/([a-zA-Z0-9.-]+(:[a-zA-Z0-9.&%$-]+)*@)*((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(:[0-9]+)*(\/($|[a-zA-Z0-9.,?'\\+&%$#=~_-]+))*$/
|
||||
return reg.test(url)
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -63,8 +67,8 @@ export function validURL(url) {
|
|||
* @returns {Boolean}
|
||||
*/
|
||||
export function validLowerCase(str) {
|
||||
const reg = /^[a-z]+$/
|
||||
return reg.test(str)
|
||||
const reg = /^[a-z]+$/
|
||||
return reg.test(str)
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -72,8 +76,8 @@ export function validLowerCase(str) {
|
|||
* @returns {Boolean}
|
||||
*/
|
||||
export function validUpperCase(str) {
|
||||
const reg = /^[A-Z]+$/
|
||||
return reg.test(str)
|
||||
const reg = /^[A-Z]+$/
|
||||
return reg.test(str)
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -81,8 +85,8 @@ export function validUpperCase(str) {
|
|||
* @returns {Boolean}
|
||||
*/
|
||||
export function validAlphabets(str) {
|
||||
const reg = /^[A-Za-z]+$/
|
||||
return reg.test(str)
|
||||
const reg = /^[A-Za-z]+$/
|
||||
return reg.test(str)
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -90,8 +94,9 @@ export function validAlphabets(str) {
|
|||
* @returns {Boolean}
|
||||
*/
|
||||
export function validEmail(email) {
|
||||
const reg = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
|
||||
return reg.test(email)
|
||||
const reg =
|
||||
/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
|
||||
return reg.test(email)
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -99,7 +104,7 @@ export function validEmail(email) {
|
|||
* @returns {Boolean}
|
||||
*/
|
||||
export function isString(str) {
|
||||
return typeof str === 'string' || str instanceof String
|
||||
return typeof str === 'string' || str instanceof String
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -107,8 +112,60 @@ export function isString(str) {
|
|||
* @returns {Boolean}
|
||||
*/
|
||||
export function isArray(arg) {
|
||||
if (typeof Array.isArray === 'undefined') {
|
||||
return Object.prototype.toString.call(arg) === '[object Array]'
|
||||
}
|
||||
return Array.isArray(arg)
|
||||
if (typeof Array.isArray === 'undefined') {
|
||||
return Object.prototype.toString.call(arg) === '[object Array]'
|
||||
}
|
||||
return Array.isArray(arg)
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证新密码(用于 Element UI 表单验证规则)
|
||||
* @param {Object} rule 验证规则对象
|
||||
* @param {string} value 密码值
|
||||
* @param {Function} callback 回调函数
|
||||
*/
|
||||
export function validateNewPassword(rule, value, callback) {
|
||||
if (!value) {
|
||||
callback(new Error('密码不能为空'))
|
||||
return
|
||||
}
|
||||
// 1. 检查密码长度
|
||||
if (value.length < 8 || value.length > 16) {
|
||||
callback(new Error('密码长度应为8至16位,且必须包含大小写字母及数字及特殊字符!'))
|
||||
return
|
||||
}
|
||||
// 2. 检查密码复杂度
|
||||
const hasUpperCase = /[A-Z]/.test(value)
|
||||
const hasLowerCase = /[a-z]/.test(value)
|
||||
const hasDigit = /\d/.test(value)
|
||||
const hasSpecialChar = /[!@#$%^&*(),.?":{}|<>]/.test(value)
|
||||
if (!hasUpperCase || !hasLowerCase || !hasDigit || !hasSpecialChar) {
|
||||
callback(new Error('密码长度应为8至16位,且必须包含大小写字母及数字及特殊字符!'))
|
||||
return
|
||||
}
|
||||
callback() // 验证成功
|
||||
}
|
||||
|
||||
/**
|
||||
* 同步验证新密码(用于 $prompt 的 inputValidator 等场景)
|
||||
* @param {string} value 密码值
|
||||
* @returns {string|boolean} 返回错误信息字符串或 true(验证通过)
|
||||
*/
|
||||
export function validateNewPasswordSync(value) {
|
||||
if (!value) {
|
||||
return '密码不能为空'
|
||||
}
|
||||
// 1. 检查密码长度
|
||||
if (value.length < 8 || value.length > 16) {
|
||||
return '密码长度应为8至16位,且必须包含大小写字母及数字及特殊字符!'
|
||||
}
|
||||
// 2. 检查密码复杂度
|
||||
const hasUpperCase = /[A-Z]/.test(value)
|
||||
const hasLowerCase = /[a-z]/.test(value)
|
||||
const hasDigit = /\d/.test(value)
|
||||
const hasSpecialChar = /[!@#$%^&*(),.?":{}|<>]/.test(value)
|
||||
if (!hasUpperCase || !hasLowerCase || !hasDigit || !hasSpecialChar) {
|
||||
return '密码长度应为8至16位,且必须包含大小写字母及数字及特殊字符!'
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
|
|
|||
|
|
@ -531,6 +531,7 @@ import 'splitpanes/dist/splitpanes.css'
|
|||
import CryptoUtil from '../../../api/crypto.js'
|
||||
import ComDialog from '@/components/ComDialog/index.vue'
|
||||
import ComButton from '@/components/ComButton/index.vue'
|
||||
import { validateNewPasswordSync } from '@/utils/validate'
|
||||
|
||||
const router = useRouter()
|
||||
const appStore = useAppStore()
|
||||
|
|
@ -769,13 +770,7 @@ function handleResetPwd(row) {
|
|||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
closeOnClickModal: false,
|
||||
inputPattern: /^.{5,20}$/,
|
||||
inputErrorMessage: '用户密码长度必须介于 5 和 20 之间',
|
||||
inputValidator: (value) => {
|
||||
if (/<|>|"|'|\||\\/.test(value)) {
|
||||
return '不能包含非法字符:< > " \' \\\ |'
|
||||
}
|
||||
},
|
||||
inputValidator: validateNewPasswordSync,
|
||||
})
|
||||
.then(({ value }) => {
|
||||
resetUserPwd(row.userId, value).then((response) => {
|
||||
|
|
|
|||
|
|
@ -1,59 +1,81 @@
|
|||
<template>
|
||||
<el-form ref="pwdRef" :model="user" :rules="rules" label-width="80px">
|
||||
<el-form-item label="旧密码" prop="oldPassword">
|
||||
<el-input v-model="user.oldPassword" placeholder="请输入旧密码" type="password" show-password />
|
||||
</el-form-item>
|
||||
<el-form-item label="新密码" prop="newPassword">
|
||||
<el-input v-model="user.newPassword" placeholder="请输入新密码" type="password" show-password />
|
||||
</el-form-item>
|
||||
<el-form-item label="确认密码" prop="confirmPassword">
|
||||
<el-input v-model="user.confirmPassword" placeholder="请确认新密码" type="password" show-password/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="submit">保存</el-button>
|
||||
<el-button type="danger" @click="close">关闭</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-form ref="pwdRef" :model="user" :rules="rules" label-width="80px">
|
||||
<el-form-item label="旧密码" prop="oldPassword">
|
||||
<el-input
|
||||
v-model="user.oldPassword"
|
||||
placeholder="请输入旧密码"
|
||||
type="password"
|
||||
show-password
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="新密码" prop="newPassword">
|
||||
<el-input
|
||||
v-model="user.newPassword"
|
||||
placeholder="请输入新密码"
|
||||
type="password"
|
||||
show-password
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="确认密码" prop="confirmPassword">
|
||||
<el-input
|
||||
v-model="user.confirmPassword"
|
||||
placeholder="请确认新密码"
|
||||
type="password"
|
||||
show-password
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="submit">保存</el-button>
|
||||
<el-button type="danger" @click="close">关闭</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { updateUserPwd } from "@/api/system/user"
|
||||
import { updateUserPwd } from '@/api/system/user'
|
||||
import { validateNewPassword } from '@/utils/validate'
|
||||
|
||||
const { proxy } = getCurrentInstance()
|
||||
|
||||
const user = reactive({
|
||||
oldPassword: undefined,
|
||||
newPassword: undefined,
|
||||
confirmPassword: undefined
|
||||
oldPassword: undefined,
|
||||
newPassword: undefined,
|
||||
confirmPassword: undefined,
|
||||
})
|
||||
|
||||
const equalToPassword = (rule, value, callback) => {
|
||||
if (user.newPassword !== value) {
|
||||
callback(new Error("两次输入的密码不一致"))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
if (user.newPassword !== value) {
|
||||
callback(new Error('两次输入的密码不一致'))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
}
|
||||
|
||||
const rules = ref({
|
||||
oldPassword: [{ required: true, message: "旧密码不能为空", trigger: "blur" }],
|
||||
newPassword: [{ required: true, message: "新密码不能为空", trigger: "blur" }, { min: 6, max: 20, message: "长度在 6 到 20 个字符", trigger: "blur" }, { pattern: /^[^<>"'|\\]+$/, message: "不能包含非法字符:< > \" ' \\\ |", trigger: "blur" }],
|
||||
confirmPassword: [{ required: true, message: "确认密码不能为空", trigger: "blur" }, { required: true, validator: equalToPassword, trigger: "blur" }]
|
||||
oldPassword: [{ required: true, message: '旧密码不能为空', trigger: 'blur' }],
|
||||
newPassword: [
|
||||
{ required: true, message: '新密码不能为空', trigger: 'blur' },
|
||||
{ validator: validateNewPassword, trigger: 'blur' },
|
||||
],
|
||||
confirmPassword: [
|
||||
{ required: true, message: '确认密码不能为空', trigger: 'blur' },
|
||||
{ validator: equalToPassword, trigger: 'blur' },
|
||||
],
|
||||
})
|
||||
|
||||
/** 提交按钮 */
|
||||
function submit() {
|
||||
proxy.$refs.pwdRef.validate(valid => {
|
||||
if (valid) {
|
||||
updateUserPwd(user.oldPassword, user.newPassword).then(response => {
|
||||
proxy.$modal.msgSuccess("修改成功")
|
||||
})
|
||||
}
|
||||
})
|
||||
proxy.$refs.pwdRef.validate((valid) => {
|
||||
if (valid) {
|
||||
updateUserPwd(user.oldPassword, user.newPassword).then((response) => {
|
||||
proxy.$modal.msgSuccess('修改成功')
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/** 关闭按钮 */
|
||||
function close() {
|
||||
proxy.$tab.closePage()
|
||||
proxy.$tab.closePage()
|
||||
}
|
||||
</script>
|
||||
|
|
|
|||
Loading…
Reference in New Issue