mirror of
https://github.com/Ed1s0nZ/CyberStrikeAI.git
synced 2026-05-17 21:44:43 +02:00
Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e54815e018 | |||
| 9baa99ea40 | |||
| 83a8c46db1 |
+1
-1
@@ -10,7 +10,7 @@
|
|||||||
# ============================================
|
# ============================================
|
||||||
|
|
||||||
# 前端显示的版本号(可选,不填则显示默认版本)
|
# 前端显示的版本号(可选,不填则显示默认版本)
|
||||||
version: "v1.3.8"
|
version: "v1.3.9"
|
||||||
|
|
||||||
# 服务器配置
|
# 服务器配置
|
||||||
server:
|
server:
|
||||||
|
|||||||
@@ -2142,6 +2142,10 @@ header {
|
|||||||
-webkit-background-clip: text;
|
-webkit-background-clip: text;
|
||||||
-webkit-text-fill-color: transparent;
|
-webkit-text-fill-color: transparent;
|
||||||
background-clip: text;
|
background-clip: text;
|
||||||
|
/* 允许标题在 flex 中收缩/换行,避免把右侧按钮挤压变形 */
|
||||||
|
flex: 1 1 auto;
|
||||||
|
min-width: 0;
|
||||||
|
overflow-wrap: anywhere;
|
||||||
}
|
}
|
||||||
|
|
||||||
.modal-close {
|
.modal-close {
|
||||||
@@ -7838,6 +7842,27 @@ header {
|
|||||||
color: var(--accent-color);
|
color: var(--accent-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 批量队列详情弹窗:标题很长时避免挤压右侧按钮 */
|
||||||
|
#batch-queue-detail-modal .modal-header {
|
||||||
|
align-items: flex-start;
|
||||||
|
gap: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#batch-queue-detail-modal .modal-header > div {
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#batch-queue-detail-modal .modal-header-actions {
|
||||||
|
flex-direction: row;
|
||||||
|
width: auto;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: flex-end;
|
||||||
|
}
|
||||||
|
|
||||||
|
#batch-queue-detail-modal .modal-header-actions button {
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
.batch-queue-tasks-list {
|
.batch-queue-tasks-list {
|
||||||
max-height: 500px;
|
max-height: 500px;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
@@ -7877,12 +7902,13 @@ header {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.batch-task-header .btn-small {
|
.batch-task-header .btn-small {
|
||||||
margin-left: auto;
|
margin-left: 0;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.batch-task-header .batch-task-edit-btn {
|
.batch-task-header .batch-task-edit-btn {
|
||||||
margin-left: 8px;
|
/* 仅把“编辑”(首个操作按钮)推到最右,避免多个按钮都 margin-left:auto 导致挤压/错位 */
|
||||||
|
margin-left: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.batch-task-header .batch-task-delete-btn {
|
.batch-task-header .batch-task-delete-btn {
|
||||||
@@ -9333,6 +9359,13 @@ header {
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
gap: 6px;
|
gap: 6px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 批量队列详情弹窗:即使在窄屏也保持按钮不“变形” */
|
||||||
|
#batch-queue-detail-modal .modal-header-actions {
|
||||||
|
flex-direction: row;
|
||||||
|
width: auto;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
.attack-chain-action-btn {
|
.attack-chain-action-btn {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|||||||
@@ -652,6 +652,50 @@ function showInlineToast(text, options) {
|
|||||||
return { el: toast, remove };
|
return { el: toast, remove };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function truncateForPreview(value, maxLen) {
|
||||||
|
const s = value == null ? '' : String(value);
|
||||||
|
if (maxLen <= 0 || s.length <= maxLen) return s;
|
||||||
|
return s.slice(0, maxLen) + '...(已截断)';
|
||||||
|
}
|
||||||
|
|
||||||
|
function formatFofaRowSummary(row, fields) {
|
||||||
|
const r = row && typeof row === 'object' ? row : {};
|
||||||
|
const order = [];
|
||||||
|
const seen = new Set();
|
||||||
|
|
||||||
|
const preferred = Array.isArray(fields) ? fields : [];
|
||||||
|
preferred.forEach(k => {
|
||||||
|
const key = String(k || '').trim();
|
||||||
|
if (!key || seen.has(key)) return;
|
||||||
|
seen.add(key);
|
||||||
|
order.push(key);
|
||||||
|
});
|
||||||
|
|
||||||
|
Object.keys(r).sort().forEach(k => {
|
||||||
|
if (seen.has(k)) return;
|
||||||
|
seen.add(k);
|
||||||
|
order.push(k);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (order.length === 0) return '-';
|
||||||
|
|
||||||
|
const lines = order.map((k) => {
|
||||||
|
const v = r[k];
|
||||||
|
let text = '';
|
||||||
|
if (v === null) text = 'null';
|
||||||
|
else if (v === undefined) text = '';
|
||||||
|
else if (typeof v === 'string') text = v === '' ? '""' : v;
|
||||||
|
else if (typeof v === 'number' || typeof v === 'boolean') text = String(v);
|
||||||
|
else {
|
||||||
|
try { text = JSON.stringify(v); } catch (e) { text = String(v); }
|
||||||
|
}
|
||||||
|
text = truncateForPreview(text, 800);
|
||||||
|
return `- ${k}: ${text}`;
|
||||||
|
});
|
||||||
|
|
||||||
|
return lines.join('\n');
|
||||||
|
}
|
||||||
|
|
||||||
function scanFofaRow(encodedRowJson, clickEvent) {
|
function scanFofaRow(encodedRowJson, clickEvent) {
|
||||||
let row = {};
|
let row = {};
|
||||||
try {
|
try {
|
||||||
@@ -674,7 +718,7 @@ function scanFofaRow(encodedRowJson, clickEvent) {
|
|||||||
window.location.hash = 'chat';
|
window.location.hash = 'chat';
|
||||||
}
|
}
|
||||||
|
|
||||||
const message = buildScanMessage(target, row);
|
const message = buildScanMessage(target, row, { fields });
|
||||||
const autoSend = !!(clickEvent && (clickEvent.ctrlKey || clickEvent.metaKey));
|
const autoSend = !!(clickEvent && (clickEvent.ctrlKey || clickEvent.metaKey));
|
||||||
|
|
||||||
setTimeout(async () => {
|
setTimeout(async () => {
|
||||||
@@ -709,15 +753,12 @@ function scanFofaRow(encodedRowJson, clickEvent) {
|
|||||||
}, 250);
|
}, 250);
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildScanMessage(target, row) {
|
function buildScanMessage(target, row, options) {
|
||||||
const title = row && row.title != null ? String(row.title).trim() : '';
|
const opts = options && typeof options === 'object' ? options : {};
|
||||||
const server = row && row.server != null ? String(row.server).trim() : '';
|
const fields = Array.isArray(opts.fields) ? opts.fields : [];
|
||||||
const hintParts = [];
|
|
||||||
if (title) hintParts.push(`title="${title}"`);
|
|
||||||
if (server) hintParts.push(`server="${server}"`);
|
|
||||||
const hint = hintParts.length ? `(FOFA提示:${hintParts.join(', ')})` : '';
|
|
||||||
|
|
||||||
return `对以下目标做信息收集与基础扫描:\n${target}\n\n要求:\n1) 识别服务/框架与关键指纹\n2) 枚举开放端口与常见管理入口\n3) 用 httpx/指纹/目录探测等方式快速确认可访问面\n4) 输出可复现的命令与结论\n\n${hint}`.trim();
|
const summary = formatFofaRowSummary(row || {}, fields);
|
||||||
|
return `对以下目标做信息收集与基础扫描:\n${target}\n\n要求:\n1) 识别服务/框架与关键指纹\n2) 枚举开放端口与常见管理入口\n3) 用 httpx/指纹/目录探测等方式快速确认可访问面\n4) 输出可复现的命令与结论\n\n已知信息(来自 FOFA 该行全部字段):\n${summary}`.trim();
|
||||||
}
|
}
|
||||||
|
|
||||||
function bindFofaTableEvents() {
|
function bindFofaTableEvents() {
|
||||||
@@ -935,6 +976,7 @@ async function batchScanSelectedFofaRows() {
|
|||||||
const fields = p.fields || [];
|
const fields = p.fields || [];
|
||||||
const tasks = [];
|
const tasks = [];
|
||||||
const skipped = [];
|
const skipped = [];
|
||||||
|
|
||||||
selected.forEach(idx => {
|
selected.forEach(idx => {
|
||||||
const row = p.results[idx];
|
const row = p.results[idx];
|
||||||
const target = inferTargetFromRow(row || {}, fields);
|
const target = inferTargetFromRow(row || {}, fields);
|
||||||
@@ -942,7 +984,10 @@ async function batchScanSelectedFofaRows() {
|
|||||||
skipped.push(idx + 1);
|
skipped.push(idx + 1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
tasks.push(buildScanMessage(target, row || {}));
|
// 批量任务:与单条一致,只带“该行全部字段”的摘要(避免重复与超长)
|
||||||
|
tasks.push(buildScanMessage(target, row || {}, {
|
||||||
|
fields
|
||||||
|
}));
|
||||||
});
|
});
|
||||||
|
|
||||||
if (tasks.length === 0) {
|
if (tasks.length === 0) {
|
||||||
|
|||||||
@@ -1197,7 +1197,8 @@ async function showBatchQueueDetail(queueId) {
|
|||||||
batchQueuesState.currentQueueId = queueId;
|
batchQueuesState.currentQueueId = queueId;
|
||||||
|
|
||||||
if (title) {
|
if (title) {
|
||||||
title.textContent = queue.title ? `批量任务队列 - ${escapeHtml(queue.title)}` : '批量任务队列';
|
// textContent 本身会做转义;这里不要再 escapeHtml,否则会把 && 显示成 &...(看起来像“变形/乱码”)
|
||||||
|
title.textContent = queue.title ? `批量任务队列 - ${String(queue.title)}` : '批量任务队列';
|
||||||
}
|
}
|
||||||
|
|
||||||
// 更新按钮显示
|
// 更新按钮显示
|
||||||
|
|||||||
@@ -1770,10 +1770,10 @@ version: 1.0.0<br>
|
|||||||
<h2 id="batch-queue-detail-title">批量任务队列详情</h2>
|
<h2 id="batch-queue-detail-title">批量任务队列详情</h2>
|
||||||
<div style="display: flex; align-items: center; gap: 12px;">
|
<div style="display: flex; align-items: center; gap: 12px;">
|
||||||
<div class="modal-header-actions">
|
<div class="modal-header-actions">
|
||||||
<button class="btn-secondary" id="batch-queue-add-task-btn" onclick="showAddBatchTaskModal()" style="display: none;">添加任务</button>
|
<button class="btn-secondary btn-small" id="batch-queue-add-task-btn" onclick="showAddBatchTaskModal()" style="display: none;">添加任务</button>
|
||||||
<button class="btn-primary" id="batch-queue-start-btn" onclick="startBatchQueue()" style="display: none;">开始执行</button>
|
<button class="btn-primary btn-small" id="batch-queue-start-btn" onclick="startBatchQueue()" style="display: none;">开始执行</button>
|
||||||
<button class="btn-secondary" id="batch-queue-pause-btn" onclick="pauseBatchQueue()" style="display: none;">暂停队列</button>
|
<button class="btn-secondary btn-small" id="batch-queue-pause-btn" onclick="pauseBatchQueue()" style="display: none;">暂停队列</button>
|
||||||
<button class="btn-secondary btn-danger" id="batch-queue-delete-btn" onclick="deleteBatchQueue()" style="display: none;">删除队列</button>
|
<button class="btn-secondary btn-small btn-danger" id="batch-queue-delete-btn" onclick="deleteBatchQueue()" style="display: none;">删除队列</button>
|
||||||
</div>
|
</div>
|
||||||
<span class="modal-close" onclick="closeBatchQueueDetailModal()">×</span>
|
<span class="modal-close" onclick="closeBatchQueueDetailModal()">×</span>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user