mirror of
https://github.com/Ed1s0nZ/CyberStrikeAI.git
synced 2026-05-15 12:58:01 +02:00
Add files via upload
This commit is contained in:
+1875
File diff suppressed because it is too large
Load Diff
@@ -103,7 +103,8 @@ async function refreshDashboard() {
|
||||
recentVulnsRes, rolesRes, agentsRes,
|
||||
openCriticalRes, openHighRes, openMediumRes, openLowRes, toolsConfigRes,
|
||||
hitlPendingRes, notificationsRes, externalMcpStatsRes,
|
||||
webshellRes
|
||||
webshellRes,
|
||||
c2ListenersRes, c2SessionsRes, c2TasksRes
|
||||
] = await Promise.all([
|
||||
fetchJson('/api/agent-loop/tasks'),
|
||||
fetchJson('/api/vulnerabilities/stats'),
|
||||
@@ -129,7 +130,11 @@ async function refreshDashboard() {
|
||||
// External MCP 健康度
|
||||
fetchJson('/api/external-mcp/stats'),
|
||||
// WebShell 已建立的连接(pentest 落地后的 foothold,对运营场景非常关键)
|
||||
fetchJson('/api/webshell/connections')
|
||||
fetchJson('/api/webshell/connections'),
|
||||
// C2 仪表盘条:监听器 / 会话 / 待处理任务(任务接口含 pending_queued_count)
|
||||
fetchJson('/api/c2/listeners'),
|
||||
fetchJson('/api/c2/sessions?limit=500'),
|
||||
fetchJson('/api/c2/tasks?page=1&page_size=1')
|
||||
]);
|
||||
|
||||
// 如果在 await 期间 controller 已被 abort,说明又有新刷新启动了,丢弃本次结果
|
||||
@@ -393,6 +398,9 @@ async function refreshDashboard() {
|
||||
// 「最近事件」内联展示(来自通知摘要,过滤掉已经被仪表盘其他位置覆盖的类型)
|
||||
renderRecentEvents(notificationsRes);
|
||||
|
||||
// C2 概览条(监听器 / 在线会话 / 待处理任务)
|
||||
renderDashboardC2Overview(c2ListenersRes, c2SessionsRes, c2TasksRes);
|
||||
|
||||
// 关键提醒条:把所有可能的告警源(漏洞/HITL/失败率/MCP健康)合并展示
|
||||
renderDashboardAlertBanner({
|
||||
criticalCount: openCriticalCount,
|
||||
@@ -444,6 +452,8 @@ async function refreshDashboard() {
|
||||
['tools', 'skills', 'knowledge', 'roles', 'agents', 'webshell'].forEach(function (k) {
|
||||
setEl('dashboard-resource-' + k, '-');
|
||||
});
|
||||
var c2secErr = document.getElementById('dashboard-section-c2');
|
||||
if (c2secErr) c2secErr.hidden = true;
|
||||
setRecentVulnsError();
|
||||
renderDashboardToolsBar(null);
|
||||
var ph = document.getElementById('dashboard-tools-pie-placeholder');
|
||||
@@ -458,6 +468,53 @@ async function refreshDashboard() {
|
||||
}
|
||||
}
|
||||
|
||||
/** C2 概览条:依赖 /api/c2/listeners、sessions、tasks;任一路由失败则整块隐藏 */
|
||||
function renderDashboardC2Overview(listenersRes, sessionsRes, tasksRes) {
|
||||
var section = document.getElementById('dashboard-section-c2');
|
||||
if (!section) return;
|
||||
if (listenersRes === null && sessionsRes === null && tasksRes === null) {
|
||||
section.hidden = true;
|
||||
return;
|
||||
}
|
||||
var running = '-';
|
||||
if (listenersRes && Array.isArray(listenersRes.listeners)) {
|
||||
running = String(listenersRes.listeners.filter(function (l) {
|
||||
return (l && (l.status || '').toLowerCase() === 'running');
|
||||
}).length);
|
||||
} else if (listenersRes === null) {
|
||||
running = '-';
|
||||
} else {
|
||||
running = '0';
|
||||
}
|
||||
var online = '-';
|
||||
if (sessionsRes && Array.isArray(sessionsRes.sessions)) {
|
||||
online = String(sessionsRes.sessions.filter(function (s) {
|
||||
if (!s) return false;
|
||||
var st = (s.status || '').toLowerCase();
|
||||
return st === 'active' || st === 'sleeping';
|
||||
}).length);
|
||||
} else if (sessionsRes === null) {
|
||||
online = '-';
|
||||
} else {
|
||||
online = '0';
|
||||
}
|
||||
var pending = '-';
|
||||
if (tasksRes && typeof tasksRes.pending_queued_count === 'number') {
|
||||
pending = String(tasksRes.pending_queued_count);
|
||||
} else if (tasksRes === null) {
|
||||
pending = '-';
|
||||
} else {
|
||||
pending = '0';
|
||||
}
|
||||
setEl('dashboard-c2-listeners-running', running);
|
||||
setEl('dashboard-c2-sessions-online', online);
|
||||
setEl('dashboard-c2-tasks-pending', pending);
|
||||
section.hidden = false;
|
||||
if (typeof applyTranslations === 'function') {
|
||||
try { applyTranslations(section); } catch (_e) { /* ignore */ }
|
||||
}
|
||||
}
|
||||
|
||||
function setEl(id, text) {
|
||||
const el = document.getElementById(id);
|
||||
if (el) el.textContent = text;
|
||||
|
||||
@@ -142,6 +142,11 @@ function einoMainStreamPlanningTitle(responseData) {
|
||||
const label = typeof window.t === 'function' ? window.t(key) : '输出';
|
||||
return prefix + '📝 ' + label;
|
||||
}
|
||||
// eino_single / deep / supervisor:主通道是模型流式输出,不是「规划」;模型偶发复述工具 stdout 时,旧文案易被误认为工具结果标题。
|
||||
if (orch != null && String(orch).trim() !== '' && orch !== 'plan_execute') {
|
||||
const streamLabel = typeof window.t === 'function' ? window.t('chat.assistantStreamPhase') : '助手输出';
|
||||
return prefix + '📝 ' + streamLabel;
|
||||
}
|
||||
const plan = typeof window.t === 'function' ? window.t('chat.planning') : '规划中';
|
||||
return prefix + '📝 ' + plan;
|
||||
}
|
||||
@@ -1498,7 +1503,7 @@ function handleStreamEvent(event, progressElement, progressId,
|
||||
const itemId = addTimelineItem(timeline, 'thinking', {
|
||||
title: title,
|
||||
message: ' ',
|
||||
data: responseData
|
||||
data: Object.assign({}, responseData, { responseStreamPlaceholder: true })
|
||||
});
|
||||
responseStreamStateByProgressId.set(progressId, { itemId: itemId, buffer: '', streamMeta: responseData });
|
||||
break;
|
||||
@@ -2198,6 +2203,9 @@ function addTimelineItem(timeline, type, options) {
|
||||
if (options.data && options.data.orchestration != null && String(options.data.orchestration).trim() !== '') {
|
||||
item.dataset.orchestration = String(options.data.orchestration).trim();
|
||||
}
|
||||
if (options.data && options.data.responseStreamPlaceholder === true) {
|
||||
item.dataset.responseStreamPlaceholder = '1';
|
||||
}
|
||||
|
||||
// 使用传入的createdAt时间,如果没有则使用当前时间(向后兼容)
|
||||
let eventTime;
|
||||
@@ -3154,7 +3162,12 @@ function refreshProgressAndTimelineI18n() {
|
||||
titleSpan.textContent = ap + _t('chat.iterationRound', { n: n });
|
||||
}
|
||||
} else if (type === 'thinking') {
|
||||
if (item.dataset.orchestration === 'plan_execute' && item.dataset.einoAgent && typeof einoMainStreamPlanningTitle === 'function') {
|
||||
if (item.dataset.responseStreamPlaceholder === '1' && typeof einoMainStreamPlanningTitle === 'function') {
|
||||
titleSpan.textContent = einoMainStreamPlanningTitle({
|
||||
orchestration: item.dataset.orchestration || '',
|
||||
einoAgent: item.dataset.einoAgent || ''
|
||||
});
|
||||
} else if (item.dataset.orchestration === 'plan_execute' && item.dataset.einoAgent && typeof einoMainStreamPlanningTitle === 'function') {
|
||||
titleSpan.textContent = einoMainStreamPlanningTitle({
|
||||
orchestration: 'plan_execute',
|
||||
einoAgent: item.dataset.einoAgent
|
||||
@@ -3163,10 +3176,10 @@ function refreshProgressAndTimelineI18n() {
|
||||
titleSpan.textContent = ap + '\uD83E\uDD14 ' + _t('chat.aiThinking');
|
||||
}
|
||||
} else if (type === 'planning') {
|
||||
if (item.dataset.orchestration === 'plan_execute' && item.dataset.einoAgent && typeof einoMainStreamPlanningTitle === 'function') {
|
||||
if (item.dataset.orchestration && typeof einoMainStreamPlanningTitle === 'function') {
|
||||
titleSpan.textContent = einoMainStreamPlanningTitle({
|
||||
orchestration: 'plan_execute',
|
||||
einoAgent: item.dataset.einoAgent
|
||||
orchestration: item.dataset.orchestration,
|
||||
einoAgent: item.dataset.einoAgent || ''
|
||||
});
|
||||
} else {
|
||||
titleSpan.textContent = ap + '\uD83D\uDCDD ' + _t('chat.planning');
|
||||
|
||||
@@ -129,6 +129,7 @@
|
||||
if ((item.type === 'task_completed' || item.type === 'long_running_tasks') && item.conversationId) return true;
|
||||
if (item.type === 'task_failed' && item.executionId) return true;
|
||||
if (item.type === 'hitl_pending') return true;
|
||||
if (item.type === 'c2_session_online' && item.sessionId) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -153,6 +154,24 @@
|
||||
}
|
||||
if (item.type === 'hitl_pending') {
|
||||
window.location.hash = 'hitl';
|
||||
return;
|
||||
}
|
||||
if (item.type === 'c2_session_online' && item.sessionId) {
|
||||
if (typeof window.switchPage === 'function') {
|
||||
window.switchPage('c2-sessions');
|
||||
} else {
|
||||
window.location.hash = 'c2-sessions';
|
||||
}
|
||||
const sid = item.sessionId;
|
||||
window.setTimeout(function () {
|
||||
if (typeof C2 === 'undefined' || !C2.loadSessions || !C2.selectSession) return;
|
||||
var p = C2.loadSessions();
|
||||
if (p && typeof p.then === 'function') {
|
||||
p.then(function () { C2.selectSession(sid); }).catch(function () {});
|
||||
} else {
|
||||
window.setTimeout(function () { try { C2.selectSession(sid); } catch (e) {} }, 500);
|
||||
}
|
||||
}, 120);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+25
-2
@@ -50,7 +50,7 @@ function initRouter() {
|
||||
if (hash) {
|
||||
const hashParts = hash.split('?');
|
||||
const pageId = hashParts[0];
|
||||
if (pageId && ['dashboard', 'chat', 'hitl', 'info-collect', 'vulnerabilities', 'webshell', 'chat-files', 'mcp-monitor', 'mcp-management', 'knowledge-management', 'knowledge-retrieval-logs', 'roles-management', 'skills-monitor', 'skills-management', 'agents-management', 'settings', 'tasks'].includes(pageId)) {
|
||||
if (pageId && ['dashboard', 'chat', 'hitl', 'info-collect', 'vulnerabilities', 'webshell', 'chat-files', 'mcp-monitor', 'mcp-management', 'knowledge-management', 'knowledge-retrieval-logs', 'roles-management', 'skills-monitor', 'skills-management', 'agents-management', 'settings', 'tasks', 'c2', 'c2-listeners', 'c2-sessions', 'c2-tasks', 'c2-payloads', 'c2-events', 'c2-profiles'].includes(pageId)) {
|
||||
switchPage(pageId);
|
||||
if (pageId === 'chat') {
|
||||
scheduleChatConversationFromHash(500);
|
||||
@@ -151,6 +151,17 @@ function updateNavState(pageId) {
|
||||
if (submenuItem) {
|
||||
submenuItem.classList.add('active');
|
||||
}
|
||||
} else if (pageId.startsWith('c2') || pageId === 'c2-listeners' || pageId === 'c2-sessions' || pageId === 'c2-tasks' || pageId === 'c2-payloads' || pageId === 'c2-events' || pageId === 'c2-profiles') {
|
||||
// C2 子菜单项
|
||||
const c2Item = document.querySelector('.nav-item[data-page="c2"]');
|
||||
if (c2Item) {
|
||||
c2Item.classList.add('active');
|
||||
c2Item.classList.add('expanded');
|
||||
}
|
||||
const submenuItem = document.querySelector(`.nav-submenu-item[data-page="${pageId}"]`);
|
||||
if (submenuItem) {
|
||||
submenuItem.classList.add('active');
|
||||
}
|
||||
} else if (pageId === 'roles-management') {
|
||||
// 角色子菜单项
|
||||
const rolesItem = document.querySelector('.nav-item[data-page="roles"]');
|
||||
@@ -405,6 +416,18 @@ async function initPage(pageId) {
|
||||
loadMarkdownAgents();
|
||||
}
|
||||
break;
|
||||
case 'c2':
|
||||
case 'c2-listeners':
|
||||
case 'c2-sessions':
|
||||
case 'c2-tasks':
|
||||
case 'c2-payloads':
|
||||
case 'c2-events':
|
||||
case 'c2-profiles':
|
||||
window.currentPageId = pageId;
|
||||
if (window.C2 && typeof window.C2.init === 'function') {
|
||||
window.C2.init();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// 清理其他页面的定时器
|
||||
@@ -425,7 +448,7 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
const hashParts = hash.split('?');
|
||||
const pageId = hashParts[0];
|
||||
|
||||
if (pageId && ['chat', 'hitl', 'info-collect', 'tasks', 'vulnerabilities', 'webshell', 'chat-files', 'mcp-monitor', 'mcp-management', 'knowledge-management', 'knowledge-retrieval-logs', 'roles-management', 'skills-monitor', 'skills-management', 'agents-management', 'settings'].includes(pageId)) {
|
||||
if (pageId && ['dashboard', 'chat', 'hitl', 'info-collect', 'tasks', 'vulnerabilities', 'webshell', 'chat-files', 'mcp-monitor', 'mcp-management', 'knowledge-management', 'knowledge-retrieval-logs', 'roles-management', 'skills-monitor', 'skills-management', 'agents-management', 'settings', 'c2', 'c2-listeners', 'c2-sessions', 'c2-tasks', 'c2-payloads', 'c2-events', 'c2-profiles'].includes(pageId)) {
|
||||
switchPage(pageId);
|
||||
if (pageId === 'chat') {
|
||||
scheduleChatConversationFromHash(200);
|
||||
|
||||
Reference in New Issue
Block a user