mirror of
https://github.com/Ed1s0nZ/CyberStrikeAI.git
synced 2026-07-10 22:33:48 +02:00
104 lines
2.9 KiB
JavaScript
104 lines
2.9 KiB
JavaScript
/** Capture filtering and HAR entry normalization. */
|
|
|
|
const STATIC_EXT =
|
|
/\.(js|css|png|jpe?g|gif|svg|webp|ico|woff2?|ttf|eot|map|wasm)(\?|$)/i;
|
|
|
|
const STATIC_MIME_PREFIXES = [
|
|
'image/',
|
|
'font/',
|
|
'audio/',
|
|
'video/',
|
|
'text/css',
|
|
];
|
|
|
|
function inferResourceType(url, responseHeaders) {
|
|
if (STATIC_EXT.test(url || '')) return 'static';
|
|
const ct = headerValue(responseHeaders, 'content-type').toLowerCase();
|
|
for (const p of STATIC_MIME_PREFIXES) {
|
|
if (ct.startsWith(p)) return 'static';
|
|
}
|
|
return 'other';
|
|
}
|
|
|
|
function headerValue(headers, name) {
|
|
if (!headers || !headers.length) return '';
|
|
const lower = name.toLowerCase();
|
|
for (const h of headers) {
|
|
if ((h.name || '').toLowerCase() === lower) return h.value || '';
|
|
}
|
|
return '';
|
|
}
|
|
|
|
function headerLines(headers) {
|
|
if (!headers || !headers.length) return '';
|
|
return headers.map((h) => `${h.name}: ${h.value}`).join('\n');
|
|
}
|
|
|
|
function truncate(str, max) {
|
|
if (!str || str.length <= max) return str || '';
|
|
return str.slice(0, max) + '\n… [truncated]';
|
|
}
|
|
|
|
function shouldCaptureEntry(entry, filterApiOnly) {
|
|
if (!entry || !entry.url) return false;
|
|
return mightCaptureRequest(entry.url, entry.resourceType, filterApiOnly);
|
|
}
|
|
|
|
/** Fast pre-filter before reading response body in devtools. */
|
|
function mightCaptureRequest(url, resourceType, filterApiOnly) {
|
|
const rt = (resourceType || inferResourceType(url, null) || 'other').toLowerCase();
|
|
if (filterApiOnly) {
|
|
return rt === 'xhr' || rt === 'fetch' || rt === 'websocket';
|
|
}
|
|
if (rt === 'static') return false;
|
|
if (STATIC_EXT.test(url || '')) return false;
|
|
return true;
|
|
}
|
|
|
|
function summarizeHarEntry(harEntry, responseBody, resourceType) {
|
|
const req = harEntry.request || {};
|
|
const res = harEntry.response || {};
|
|
const url = req.url || '';
|
|
let path = '/';
|
|
try {
|
|
const u = new URL(url);
|
|
path = u.pathname + (u.search || '');
|
|
} catch (_) {
|
|
path = url;
|
|
}
|
|
const shortPath = path.length > 80 ? path.slice(0, 77) + '...' : path;
|
|
const title = `${req.method || 'GET'} ${shortPath}`;
|
|
|
|
return {
|
|
id: `${Date.now()}_${Math.random().toString(36).slice(2, 8)}`,
|
|
title,
|
|
method: req.method || 'GET',
|
|
url,
|
|
resourceType: resourceType || 'other',
|
|
requestHeaders: headerLines(req.headers),
|
|
requestBody: truncate((req.postData && req.postData.text) || '', CSAI_LIMITS.MAX_REQUEST_BODY),
|
|
responseStatus: res.status,
|
|
responseHeaders: headerLines(res.headers),
|
|
responseBody: truncate(responseBody || '', CSAI_LIMITS.MAX_RESPONSE_BODY),
|
|
capturedAt: Date.now(),
|
|
};
|
|
}
|
|
|
|
function summarizePageContext(page) {
|
|
return {
|
|
id: `page_${Date.now()}`,
|
|
title: `PAGE ${page.title || page.url || ''}`.slice(0, 80),
|
|
method: 'PAGE',
|
|
url: page.url || '',
|
|
resourceType: 'document',
|
|
requestHeaders: '',
|
|
requestBody: '',
|
|
responseStatus: 0,
|
|
responseHeaders: '',
|
|
responseBody: '',
|
|
pageTitle: page.title || '',
|
|
isPageContext: true,
|
|
capturedAt: Date.now(),
|
|
};
|
|
}
|