feat(login-guard): unlock entire scope and report deleted keys
Admin login-lock reset now SCANs and clears all auth:login:* keys (any scope) and surfaces redis_deleted_keys / fallback_deleted_keys back to ops-web so the operator can tell whether the cache was actually hit. Also tracks paired keys via a per-identifier index plus an unlock marker so legacy/in-flight pair locks get cleared on the next acquire. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -138,7 +138,7 @@
|
||||
</a-button>
|
||||
</a-tooltip>
|
||||
|
||||
<a-tooltip title="重置登录保护">
|
||||
<a-tooltip title="清除登录锁定">
|
||||
<a-popconfirm
|
||||
title="确认清除该用户的登录锁定状态?"
|
||||
:ok-button-props="{ loading: resetLoginLockLoadingId === record.id }"
|
||||
@@ -363,6 +363,15 @@ interface ResetPlanUsageResult {
|
||||
}
|
||||
}
|
||||
|
||||
interface ResetLoginLockResult {
|
||||
id: number
|
||||
redis_deleted_keys: number
|
||||
fallback_deleted_keys: number
|
||||
redis_scan_patterns: string[]
|
||||
redis_addr?: string
|
||||
redis_db: number
|
||||
}
|
||||
|
||||
const filter = reactive({
|
||||
keyword: '',
|
||||
status: undefined as string | undefined,
|
||||
@@ -626,8 +635,14 @@ const resetLoginLockLoadingId = ref<number | null>(null)
|
||||
async function resetLoginLock(row: AdminUserRow) {
|
||||
resetLoginLockLoadingId.value = row.id
|
||||
try {
|
||||
await http.post(`/admin-users/${row.id}/reset-login-lock`)
|
||||
message.success('登录保护已重置,用户可立即重新登录')
|
||||
const result = await http.post<ResetLoginLockResult>(`/admin-users/${row.id}/reset-login-lock`)
|
||||
if (result.redis_deleted_keys > 0) {
|
||||
message.success(`登录锁定已清除,已删除 ${result.redis_deleted_keys} 个 Redis key`)
|
||||
} else if (result.fallback_deleted_keys > 0) {
|
||||
message.success(`登录锁定已清除,已清理 ${result.fallback_deleted_keys} 个本机保护状态`)
|
||||
} else {
|
||||
message.warning('未发现登录锁 Redis key,请检查 ops-api 与 admin-web 使用的 Redis 地址和 DB 是否一致')
|
||||
}
|
||||
} catch (error) {
|
||||
if (error instanceof OpsApiError) message.error(error.detail || error.message)
|
||||
} finally {
|
||||
|
||||
Reference in New Issue
Block a user