Skip to content

Commit 9e4c417

Browse files
committed
fix: normalize module tabs to avoid duplicate AutoAR labels
Canonicalize module keys before building tabs and applying module filters so alias/unknown values do not render as repeated AutoAR tabs. Made-with: Cursor
1 parent 0bfe8ea commit 9e4c417

1 file changed

Lines changed: 24 additions & 8 deletions

File tree

  • internal/modules/gobot/ui

internal/modules/gobot/ui/app.js

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1887,9 +1887,23 @@ function detectModuleFromFileName(fileName, existingModule) {
18871887
return 'autoar';
18881888
}
18891889

1890+
/** Get module display name with icon */
1891+
function normalizeModuleKey(module) {
1892+
const raw = String(module || '').toLowerCase().trim();
1893+
if (!raw) return 'unknown';
1894+
const aliases = {
1895+
'aem-scan': 'aem',
1896+
'ffuf': 'ffuf-fuzzing',
1897+
'dns': 'dns-takeover',
1898+
'dep-confusion': 'dependency-confusion',
1899+
'dependency_confusion': 'dependency-confusion',
1900+
};
1901+
return aliases[raw] || raw;
1902+
}
1903+
18901904
/** Get module display name with icon */
18911905
function getModuleDisplayInfo(module) {
1892-
const mod = String(module || '').toLowerCase();
1906+
const mod = normalizeModuleKey(module);
18931907
const modules = {
18941908
'nuclei': { icon: '🚨', name: 'Nuclei', color: '#ef4444' },
18951909
'subdomain-enum': { icon: '🔗', name: 'Subdomains', color: '#6366f1' },
@@ -1918,7 +1932,7 @@ function getModuleDisplayInfo(module) {
19181932
'unknown': { icon: '❓', name: 'Unknown', color: '#64748b' },
19191933
};
19201934

1921-
return modules[mod] || modules['autoar'];
1935+
return modules[mod] || modules['unknown'];
19221936
}
19231937

19241938
// ── Module Renderers Registry ────────────────────────────────────────────────
@@ -4213,7 +4227,7 @@ async function loadReconUnifiedTable(scanId, allFiles, containerId, scanRecord)
42134227
'aem',
42144228
'github-scan',
42154229
];
4216-
const usedModulesRaw = [...new Set(allRows.map(r => String(r.module || '').toLowerCase()).filter(Boolean))];
4230+
const usedModulesRaw = [...new Set(allRows.map(r => normalizeModuleKey(r.module)).filter(Boolean))];
42174231
const usedModules = usedModulesRaw.sort((a, b) => {
42184232
const ai = preferredModuleOrder.indexOf(a);
42194233
const bi = preferredModuleOrder.indexOf(b);
@@ -4222,7 +4236,7 @@ async function loadReconUnifiedTable(scanId, allFiles, containerId, scanRecord)
42224236
if (bi !== -1) return 1;
42234237
return a.localeCompare(b);
42244238
});
4225-
const excludedModuleTabs = new Set(['autoar', 'tech-detect', 'ffuf-fuzzing']);
4239+
const excludedModuleTabs = new Set(['autoar', 'unknown', 'tech-detect', 'ffuf-fuzzing']);
42264240
const moduleTabs = usedModules.filter((mod) => !excludedModuleTabs.has(mod)).map((mod) => {
42274241
const info = getModuleDisplayInfo(mod);
42284242
return [`mod:${mod}`, `${info.icon} ${info.name}`];
@@ -4272,10 +4286,10 @@ async function loadReconUnifiedTable(scanId, allFiles, containerId, scanRecord)
42724286
const k = r.kind || 'other';
42734287
if (String(activeKind || '').startsWith('mod:')) {
42744288
const moduleKind = String(activeKind).slice(4);
4275-
if (String(r.module || '').toLowerCase() !== moduleKind) return false;
4289+
if (normalizeModuleKey(r.module) !== moduleKind) return false;
42764290
} else if (activeKind === 'vuln') {
42774291
if (!VULN_KINDS.has(k)) return false;
4278-
if (searchModule !== 'all' && (r.module || 'other') !== searchModule) return false;
4292+
if (searchModule !== 'all' && normalizeModuleKey(r.module) !== searchModule) return false;
42794293
} else if (k !== activeKind) {
42804294
return false;
42814295
}
@@ -4350,7 +4364,9 @@ async function loadReconUnifiedTable(scanId, allFiles, containerId, scanRecord)
43504364

43514365
const modSelect = root.querySelector('#recon-filter-module');
43524366
if (modSelect) {
4353-
const usedModules = [...new Set(allRows.map(r => r.module || 'other'))].sort();
4367+
const usedModules = [...new Set(allRows.map(r => normalizeModuleKey(r.module)))]
4368+
.filter((m) => m && m !== 'unknown')
4369+
.sort();
43544370
modSelect.innerHTML = '<option value="all">All Modules</option>' + usedModules.map(m => {
43554371
return `<option value="${esc(m)}">${esc(getModuleDisplayInfo(m).name)}</option>`;
43564372
}).join('');
@@ -4367,7 +4383,7 @@ async function loadReconUnifiedTable(scanId, allFiles, containerId, scanRecord)
43674383
const isModuleTab = String(kind).startsWith('mod:');
43684384
const moduleKind = isModuleTab ? String(kind).slice(4) : '';
43694385
const count = isModuleTab
4370-
? allRows.filter(r => String(r.module || '').toLowerCase() === moduleKind).length
4386+
? allRows.filter(r => normalizeModuleKey(r.module) === moduleKind).length
43714387
: ((kind === 'assets' || kind === 'vuln') ? datasetCount(kind) : (kindCounts[kind] || 0));
43724388
const cntDisplay = count > 0 ? `<span class="tab-count">${count}</span>` : '';
43734389
return `<button class="tab-pill${isActive ? ' active' : ''}" data-recon-kind="${escAttr(kind)}" style="border:none;border-bottom:2px solid ${isActive ? 'var(--accent-cyan)' : 'transparent'};border-radius:0;padding:11px 12px;white-space:nowrap;background:transparent;color:${isActive ? 'var(--accent-cyan)' : 'var(--text-secondary)'};font-size:12px">

0 commit comments

Comments
 (0)