Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion ui/src/views/system/identity/users/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,7 @@ onMounted(() => loadSystemUsers())
<ButtonChangeUserPassword v-if="perm.system.user.edit()" :user="row" @refresh="loadSystemUsers(false)" />
<!-- 删除 -->
<MkTooltip content="删除" placement="top" v-if="perm.system.user.delete()">
<el-button type="primary" text @click.stop="deleteUser(row)">
<el-button type="primary" :disabled="row.id === user.userInfo?.id" text @click.stop="deleteUser(row)">
<MkIcon name="icon_delete-trash_outlined" />
</el-button>
</MkTooltip>

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Summary: The change disables the delete button for the currently logged-in user, preventing self-deletion. This is a sensible safeguard.

Issues & Suggestions:

  1. UX: Disabled button with no explanation. Users won't know why they can't delete their own account. Consider adding a tooltip/explanation when disabled:

    <MkTooltip :content="row.id === user.userInfo?.id ? '不能删除当前登录用户' : '删除'" placement="top">

    Or better, hide the button entirely for one's own row.

  2. Defense in depth: backend validation. Frontend disabling alone is insufficient—ensure the server also rejects attempts to delete the currently authenticated user (or at least another admin deleting themselves). The frontend check can be bypassed via API calls.

  3. Type/null-safety of user.userInfo?.id. If user.userInfo is undefined, row.id === undefined will be false, so the guard silently fails open (button enabled). Consider a stricter comparison:

    const isCurrentUser = computed(() => !!user.userInfo?.id && row.id === user.userInfo.id)

    Also confirm row.id and userInfo.id are the same type (number vs string)—mismatched types would break equality.

  4. Extract to a computed/method for reuse. If similar guards are needed elsewhere (e.g., edit, disable-account), factoring this into a helper improves consistency and readability.

  5. Consider hiding vs. disabling. For destructive actions, v-if="row.id !== user.userInfo?.id" avoids the "why can't I click this?" confusion and reduces accidental clicks—though disabling can be preferable if you want to signal the restriction explicitly.

Overall, the change is reasonable; the main gaps are backend enforcement and clearer UX messaging.

Expand Down
Loading