fix: 踢下线同时禁用账号防重连,禁止管理员踢自己
- handler/vpn.go: KickUserClient 踢线后设置 status=0 并失效所有会话, 阻止客户端自动重连;新增自检,目标为当前管理员时返回 400 - AdminView.vue: handleKick 调用 API 前自检,自己则提示去修改密码 - zh.ts/en.ts: 新增 cannotKickSelf,更新 confirmKick 提示含禁用账号
This commit is contained in:
@@ -150,8 +150,9 @@ export default {
|
|||||||
selectUserAndIp: 'Please select a user and fill in at least one IP address',
|
selectUserAndIp: 'Please select a user and fill in at least one IP address',
|
||||||
confirmDeleteReservation: 'Delete this reservation?',
|
confirmDeleteReservation: 'Delete this reservation?',
|
||||||
kick: 'Kick',
|
kick: 'Kick',
|
||||||
confirmKick: 'Disconnect all VPN connections for user {username}?',
|
confirmKick: 'Disconnect all VPN connections for user {username} and disable their account?',
|
||||||
kickFailed: 'Failed to kick user',
|
kickFailed: 'Failed to kick user',
|
||||||
|
cannotKickSelf: 'Cannot kick yourself. To disconnect your own devices, please change your password.',
|
||||||
},
|
},
|
||||||
footer: {
|
footer: {
|
||||||
lastCommit: 'Last commit',
|
lastCommit: 'Last commit',
|
||||||
|
|||||||
@@ -149,8 +149,9 @@ export default {
|
|||||||
selectUserAndIp: '请选择用户并至少填写一个 IP 地址',
|
selectUserAndIp: '请选择用户并至少填写一个 IP 地址',
|
||||||
confirmDeleteReservation: '确认删除该预留?',
|
confirmDeleteReservation: '确认删除该预留?',
|
||||||
kick: '踢下线',
|
kick: '踢下线',
|
||||||
confirmKick: '确定要断开用户 {username} 的所有 VPN 连接吗?',
|
confirmKick: '确定要断开用户 {username} 的所有 VPN 连接并禁用其账号吗?',
|
||||||
kickFailed: '踢下线失败',
|
kickFailed: '踢下线失败',
|
||||||
|
cannotKickSelf: '不能踢自己下线,如需断开自己的设备请修改密码',
|
||||||
},
|
},
|
||||||
footer: {
|
footer: {
|
||||||
lastCommit: '最后提交',
|
lastCommit: '最后提交',
|
||||||
|
|||||||
@@ -83,8 +83,12 @@ async function fetchVpnStatus() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function handleKick(userId: number, username: string) {
|
async function handleKick(userId: number, username: string) {
|
||||||
if (!confirm(t('vpn.confirmKick', { username }))) return
|
|
||||||
kickError.value = ''
|
kickError.value = ''
|
||||||
|
if (userId === authStore.user?.id) {
|
||||||
|
kickError.value = t('vpn.cannotKickSelf')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (!confirm(t('vpn.confirmKick', { username }))) return
|
||||||
try {
|
try {
|
||||||
const res = await fetch(`/api/admin/vpn/clients/${userId}`, {
|
const res = await fetch(`/api/admin/vpn/clients/${userId}`, {
|
||||||
method: 'DELETE',
|
method: 'DELETE',
|
||||||
|
|||||||
+12
-4
@@ -421,11 +421,19 @@ func KickUserClient(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if vpn.VPN == nil || !vpn.VPN.Running() {
|
currentUserID, _ := c.Get("user_id")
|
||||||
c.JSON(http.StatusOK, gin.H{"message": "VPN 服务未运行", "kicked": 0})
|
if uint(id) == currentUserID.(uint) {
|
||||||
|
c.JSON(http.StatusBadRequest, gin.H{"error": "不能踢自己下线,如需断开自己的设备请修改密码"})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
n := vpn.VPN.KickUser(uint(id))
|
n := 0
|
||||||
c.JSON(http.StatusOK, gin.H{"message": "已断开用户连接", "kicked": n})
|
if vpn.VPN != nil && vpn.VPN.Running() {
|
||||||
|
n = vpn.VPN.KickUser(uint(id))
|
||||||
|
}
|
||||||
|
|
||||||
|
db.DB.Model(&user).Update("status", 0)
|
||||||
|
db.DB.Model(&model.Session{}).Where("user_id = ?", id).Update("invalid", true)
|
||||||
|
|
||||||
|
c.JSON(http.StatusOK, gin.H{"message": "已断开用户连接并禁用账号", "kicked": n})
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user