fix(users): 自己可改显示名、超管可在编辑里提升超管(修「保存失败/禁止修改自己的账户」)
站长反馈:在 admin 模式下仍无法修改用户信息,弹「禁止在用户管理中修改自己的账户」;
另外角色下拉里没有「技术运维」。
1) 自己改自己:原来一律禁止 → 现在**只允许改姓名(显示名)**,其余(账号名/年级/班级/
状态/角色/密码)只要动了就仍然拒绝。这样站长能在「用户管理」里把 admin 的显示名
改成自己的名字(登录名仍是 admin,应急登录不受影响)。
状态比较忽略大小写:库里是 active,客户端历史版本可能发 ACTIVE,不该因此判定"改了状态"。
2) 超管可在通用编辑接口里把别人提升为 SUPER_ADMIN(站长要求下拉里要有「技术运维」):
新增 allowPromoteBySuper 例外 —— 仅当登录者是 SUPER_ADMIN、目标角色设为 SUPER_ADMIN、
且目标不是初始账号(ID=1,本来就是超管)时放行;非超管仍被 canChangeRoleOf 拦住。
与 POST /api/admin/users/{id}/promote-super 效果一致,两条路都能走。
This commit is contained in:
@@ -109,12 +109,29 @@ export default defineEventHandler(async (event) => {
|
||||
}
|
||||
}
|
||||
|
||||
// 2. 禁止对自身进行任何用户管理操作(包括角色、资料、状态、密码等)
|
||||
/*
|
||||
* 2. 自己改自己:**只允许改姓名(显示名)**,其余一律禁止。
|
||||
*
|
||||
* 站长要在「用户管理」里把 admin 的显示名改成自己的名字(登录名仍是 admin),
|
||||
* 原来这里是"自己一律不能改",于是他只看到「禁止在用户管理中修改自己的账户」。
|
||||
* 放宽到"只有姓名变了、其它字段一个都没动"是安全的:改不了角色/状态/密码/账号名,
|
||||
* 也提不了权,只是换个显示名而已(等价于个人资料页改名字)。
|
||||
*/
|
||||
if (String(userId) === String(user.id)) {
|
||||
throw createError({
|
||||
statusCode: 400,
|
||||
statusMessage: '禁止在用户管理中修改自己的账户'
|
||||
})
|
||||
const gradeChanged = String(grade || '').trim() !== String(targetUser.grade || '').trim()
|
||||
const classChanged = String(userClass || '').trim() !== String(targetUser.class || '').trim()
|
||||
const statusChanged =
|
||||
!!status && String(status).toLowerCase() !== String(targetUser.status || '').toLowerCase()
|
||||
const roleChanged = !!role && role !== targetUser.role
|
||||
const onlyNameChanged =
|
||||
nameChanged && !usernameChanged && !gradeChanged && !classChanged && !statusChanged && !roleChanged && !password
|
||||
|
||||
if (!onlyNameChanged) {
|
||||
throw createError({
|
||||
statusCode: 400,
|
||||
statusMessage: '禁止在用户管理中修改自己的账户(自己只能改「姓名」,其它请到「设置」里操作)'
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// 3. 非超级管理员必须严格高于目标角色级别
|
||||
@@ -144,7 +161,16 @@ export default defineEventHandler(async (event) => {
|
||||
// 角色权限控制(统一使用 canChangeRoleOf 语义化检查)
|
||||
let validRole = targetUser.role
|
||||
if (role && role !== targetUser.role) {
|
||||
if (!canChangeRoleOf(user, targetUser, role)) {
|
||||
/*
|
||||
* 站长要求用户编辑表单的角色下拉里要有「技术运维」(SUPER_ADMIN)。
|
||||
* 原 canChangeRoleOf() 一律禁止提升为 SUPER_ADMIN(网页版也这么设计),
|
||||
* 这里对**超级管理员**放开这一条:只有超管能把别人提升为超管,且目标不能是初始账号(ID=1,它本来就是)。
|
||||
* 效果与 POST /api/admin/users/{id}/promote-super 一致,两条路都可用。
|
||||
*/
|
||||
const allowPromoteBySuper =
|
||||
user.role === 'SUPER_ADMIN' && role === 'SUPER_ADMIN' && targetUser.id !== 1
|
||||
|
||||
if (!allowPromoteBySuper && !canChangeRoleOf(user, targetUser, role)) {
|
||||
throw createError({
|
||||
statusCode: 403,
|
||||
statusMessage: user.role === 'SUPER_ADMIN'
|
||||
|
||||
Reference in New Issue
Block a user