diff --git a/web/static/i18n/en-US.json b/web/static/i18n/en-US.json index d9774a19..bd9752d8 100644 --- a/web/static/i18n/en-US.json +++ b/web/static/i18n/en-US.json @@ -2188,6 +2188,93 @@ "exportDone": "Export complete", "loading": "Loading...", "empty": "No audit records", + "result": { + "success": "success", + "failure": "failure" + }, + "msg": { + "auth": { + "login": "Login successful", + "login_failed": "Login failed: incorrect password", + "logout": "Logged out", + "change_password": "Login password changed", + "change_password_failed": "Password change failed: current password incorrect" + }, + "config": { + "apply": "Configuration applied", + "update": "In-memory configuration updated", + "apply_fail_kb_init": "Failed to apply config: knowledge base init", + "apply_fail_kb_reinit": "Failed to apply config: knowledge base re-init", + "apply_fail_c2": "Failed to apply config: C2" + }, + "conversation": { + "create": "Conversation created", + "delete": "Conversation deleted", + "delete_turn": "Conversation turn deleted" + }, + "c2": { + "listener_create": "C2 listener created", + "listener_delete": "C2 listener deleted", + "listener_start": "C2 listener started", + "listener_stop": "C2 listener stopped", + "session_delete": "C2 session deleted", + "task_create": "C2 task created", + "task_cancel": "C2 task cancelled", + "task_delete": "C2 tasks deleted (batch)" + }, + "webshell": { + "connection_create": "WebShell connection created", + "connection_delete": "WebShell connection deleted" + }, + "knowledge": { + "item_delete": "Knowledge item deleted", + "index_rebuild": "Knowledge index rebuilt" + }, + "vulnerability": { + "create": "Vulnerability record created", + "update": "Vulnerability record updated", + "delete": "Vulnerability record deleted", + "delete_batch": "Vulnerability records deleted (batch)" + }, + "external_mcp": { + "upsert": "External MCP configuration updated", + "delete": "External MCP configuration deleted" + }, + "task": { + "create_queue": "Batch task queue created", + "start_queue": "Batch task queue started", + "delete_queue": "Batch task queue deleted", + "pause_queue": "Batch task queue paused", + "rerun_queue": "Batch task queue rerun", + "delete_batch_task": "Batch subtask deleted" + }, + "tool": { + "execution_delete": "Tool execution record deleted", + "execution_delete_batch": "Tool execution records deleted (batch)" + }, + "file": { + "upload": "Chat attachment uploaded", + "delete": "Chat attachment deleted" + }, + "hitl": { + "decision": "HITL approval decision" + }, + "role": { + "create": "Role created", + "update": "Role updated", + "delete": "Role deleted" + }, + "skill": { + "create": "Skill created", + "update": "Skill updated", + "delete": "Skill deleted" + }, + "agent": { + "markdown_create": "Markdown sub-agent created", + "markdown_update": "Markdown sub-agent updated", + "markdown_delete": "Markdown sub-agent deleted" + } + }, "paginationShow": "{{start}}-{{end}} of {{total}}", "detailTitle": "Audit detail", "detailTime": "Time", diff --git a/web/static/i18n/zh-CN.json b/web/static/i18n/zh-CN.json index dc914bb5..6d54ea6c 100644 --- a/web/static/i18n/zh-CN.json +++ b/web/static/i18n/zh-CN.json @@ -2176,6 +2176,93 @@ "exportDone": "导出完成", "loading": "加载中...", "empty": "暂无审计记录", + "result": { + "success": "成功", + "failure": "失败" + }, + "msg": { + "auth": { + "login": "登录成功", + "login_failed": "登录失败:密码错误", + "logout": "退出登录", + "change_password": "登录密码已修改", + "change_password_failed": "修改密码失败:当前密码不正确" + }, + "config": { + "apply": "配置已应用", + "update": "更新内存配置", + "apply_fail_kb_init": "应用配置失败:初始化知识库", + "apply_fail_kb_reinit": "应用配置失败:重新初始化知识库", + "apply_fail_c2": "应用配置失败:C2" + }, + "conversation": { + "create": "创建对话", + "delete": "删除对话", + "delete_turn": "删除对话轮次" + }, + "c2": { + "listener_create": "创建 C2 监听器", + "listener_delete": "删除 C2 监听器", + "listener_start": "启动 C2 监听器", + "listener_stop": "停止 C2 监听器", + "session_delete": "删除 C2 会话", + "task_create": "创建 C2 任务", + "task_cancel": "取消 C2 任务", + "task_delete": "批量删除 C2 任务" + }, + "webshell": { + "connection_create": "创建 WebShell 连接", + "connection_delete": "删除 WebShell 连接" + }, + "knowledge": { + "item_delete": "删除知识项", + "index_rebuild": "重建知识库索引" + }, + "vulnerability": { + "create": "创建漏洞记录", + "update": "更新漏洞记录", + "delete": "删除漏洞记录", + "delete_batch": "批量删除漏洞记录" + }, + "external_mcp": { + "upsert": "更新外部 MCP 配置", + "delete": "删除外部 MCP 配置" + }, + "task": { + "create_queue": "创建批量任务队列", + "start_queue": "启动批量任务队列", + "delete_queue": "删除批量任务队列", + "pause_queue": "暂停批量任务队列", + "rerun_queue": "重跑批量任务队列", + "delete_batch_task": "删除批量子任务" + }, + "tool": { + "execution_delete": "删除工具执行记录", + "execution_delete_batch": "批量删除工具执行记录" + }, + "file": { + "upload": "上传对话附件", + "delete": "删除对话附件" + }, + "hitl": { + "decision": "HITL 审批决策" + }, + "role": { + "create": "创建角色", + "update": "更新角色", + "delete": "删除角色" + }, + "skill": { + "create": "创建 Skill", + "update": "更新 Skill", + "delete": "删除 Skill" + }, + "agent": { + "markdown_create": "创建 Markdown 子代理", + "markdown_update": "更新 Markdown 子代理", + "markdown_delete": "删除 Markdown 子代理" + } + }, "paginationShow": "显示 {{start}}-{{end}} / 共 {{total}} 条", "detailTitle": "审计详情", "detailTime": "时间", diff --git a/web/static/js/audit.js b/web/static/js/audit.js index 7b061e40..52fd7cd1 100644 --- a/web/static/js/audit.js +++ b/web/static/js/audit.js @@ -4,6 +4,7 @@ let auditLogsPage = 1; let auditLogsPageSize = 20; let auditLogsTotal = 0; +let auditLogsCache = []; const AUDIT_PAGE_SIZE_KEY = 'cyberstrike_audit_page_size'; @@ -52,6 +53,43 @@ function auditActionLabel(action) { return auditT('settingsAudit.act.' + action, null, action); } +/** Stored DB messages that share category+action but need distinct i18n keys. */ +const AUDIT_MSG_BY_STORED_TEXT = { + '登录失败:密码错误': 'settingsAudit.msg.auth.login_failed', + '修改密码失败:当前密码不正确': 'settingsAudit.msg.auth.change_password_failed', + '应用配置失败:初始化知识库': 'settingsAudit.msg.config.apply_fail_kb_init', + '应用配置失败:重新初始化知识库': 'settingsAudit.msg.config.apply_fail_kb_reinit', + '应用配置失败:C2': 'settingsAudit.msg.config.apply_fail_c2' +}; + +function auditMessageLabel(log) { + if (!log) return ''; + const raw = (log.message || '').trim(); + if (raw && AUDIT_MSG_BY_STORED_TEXT[raw]) { + return auditT(AUDIT_MSG_BY_STORED_TEXT[raw], null, raw); + } + const cat = (log.category || '').trim(); + const act = (log.action || '').trim(); + const res = (log.result || '').trim(); + if (cat && act) { + if (cat === 'auth' && act === 'login' && res === 'failure') { + return auditT('settingsAudit.msg.auth.login_failed', null, raw); + } + if (cat === 'auth' && act === 'change_password' && res === 'failure') { + return auditT('settingsAudit.msg.auth.change_password_failed', null, raw); + } + const key = 'settingsAudit.msg.' + cat + '.' + act; + const translated = auditT(key, null, null); + if (translated && translated !== key) return translated; + } + return raw; +} + +function auditResultLabel(result) { + if (!result) return ''; + return auditT('settingsAudit.result.' + result, null, result); +} + function auditLocale() { if (typeof window.__locale === 'string' && window.__locale.length) { return window.__locale.startsWith('zh') ? 'zh-CN' : 'en-US'; @@ -246,7 +284,8 @@ async function loadAuditLogs(page) { throw new Error(err.error || r.statusText); } const data = await r.json(); - renderAuditLogs(data.logs || []); + auditLogsCache = data.logs || []; + renderAuditLogs(auditLogsCache); auditLogsTotal = typeof data.total === 'number' ? data.total : 0; const maxPage = Math.max(1, Math.ceil(auditLogsTotal / auditLogsPageSize)); if (auditLogsPage > maxPage) { @@ -295,10 +334,10 @@ function renderAuditLogs(logs) { const rows = logs.map(function (log) { const catLabel = esc(auditCategoryLabel(log.category || '')); const actionLabel = esc(auditActionLabel(log.action || '')); - const msg = esc(log.message || ''); + const msg = esc(auditMessageLabel(log)); const ip = esc(log.clientIp || ''); const when = esc(formatAuditTime(log.createdAt)); - const res = esc(log.result || ''); + const res = esc(auditResultLabel(log.result || '')); const rid = log.resourceId ? esc(log.resourceId) : ''; const eid = esc(log.id || ''); const resultCls = auditResultTagClass(log.result || ''); @@ -658,8 +697,8 @@ async function showAuditLogDetail(id) { '