Skip to content

Commit a302fde

Browse files
committed
fixed validation error
1 parent 1938de6 commit a302fde

4 files changed

Lines changed: 102 additions & 5 deletions

File tree

.github/workflows/validate.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ jobs:
2626

2727
- name: Install dependencies
2828
run: |
29-
pip install -r requirements.txt
29+
pip install -r scripts/requirements.txt
3030
3131
- name: Validate YAML files
3232
run: |

docs/css/style.css

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -962,6 +962,32 @@ html.light-theme .detection-tool-circle {
962962
border-color: var(--border-color);
963963
}
964964

965+
/* Instant tooltip for detection circles */
966+
.detection-tooltip {
967+
position: fixed;
968+
background: var(--card-bg);
969+
border: 1px solid var(--border-color);
970+
border-radius: 6px;
971+
padding: 8px 12px;
972+
font-size: 0.85em;
973+
color: var(--text-color);
974+
white-space: nowrap;
975+
z-index: 1000;
976+
pointer-events: none;
977+
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
978+
opacity: 0;
979+
transition: opacity 0s; /* Instant appearance */
980+
}
981+
982+
.detection-tooltip.visible {
983+
opacity: 1;
984+
}
985+
986+
html.light-theme .detection-tooltip {
987+
background: white;
988+
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
989+
}
990+
965991
.no-detection {
966992
color: var(--text-muted);
967993
font-size: 1.2em;
@@ -977,6 +1003,7 @@ html.light-theme .detection-tool-circle {
9771003
font-size: 0.8em;
9781004
font-weight: 600;
9791005
margin-bottom: 10px;
1006+
cursor: help;
9801007
}
9811008

9821009
.category-self-escalation {

docs/js/app.js

Lines changed: 72 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,15 @@ let sortColumn = null;
88
let sortDirection = 'asc'; // 'asc' or 'desc'
99
let currentRoute = { view: 'list', pathId: null }; // Track current route
1010

11+
// Category tooltips
12+
const categoryTooltips = {
13+
'self-escalation': 'Modify your own permissions directly',
14+
'lateral-movement': 'Gain access to a different principal',
15+
'service-passrole': 'Pass a privileged role to a resource that executes code',
16+
'access-resource': 'Modify existing resources to gain elevated access',
17+
'credential-access': 'Read permissions that may expose credentials'
18+
};
19+
1120
// DOM elements
1221
const pathsContainer = document.getElementById('paths-container');
1322
const searchInput = document.getElementById('search');
@@ -50,6 +59,7 @@ document.addEventListener('DOMContentLoaded', () => {
5059
initTheme();
5160
setupEventListeners();
5261
setupTabListeners();
62+
setupInstantTooltips(); // Setup tooltips for detection circles and category chips
5363
loadPaths(); // This will call initRouter() when data is loaded
5464
});
5565

@@ -554,7 +564,7 @@ function createPathCard(path) {
554564
<div class="path-card">
555565
<div class="path-card-header">
556566
<span class="path-id">${path.id.toUpperCase()}</span>
557-
<span class="path-category ${categoryClass}">${formatCategory(path.category)}</span>
567+
<span class="path-category ${categoryClass}" data-category-tooltip="${categoryTooltips[path.category] || ''}">${formatCategory(path.category)}</span>
558568
</div>
559569
<div class="path-name">${escapeHtml(path.name)}</div>
560570
<div class="path-description">${escapeHtml(path.description)}</div>
@@ -605,13 +615,13 @@ function createPathTable(paths) {
605615
</td>
606616
<td class="table-name">${escapeHtml(path.name)}</td>
607617
<td class="table-category">
608-
<span class="path-category ${categoryClass}">${formatCategory(path.category)}</span>
618+
<span class="path-category ${categoryClass}" data-category-tooltip="${categoryTooltips[path.category] || ''}">${formatCategory(path.category)}</span>
609619
</td>
610620
<td class="table-detection">
611621
${detectionTools.length > 0 ?
612622
detectionTools.map(tool => {
613623
const toolInfo = toolMetadata[tool] || { name: tool };
614-
return `<span class="detection-tool-circle" title="${toolInfo.name || tool}" data-tool="${tool}">${getToolInitials(tool)}</span>`;
624+
return `<span class="detection-tool-circle" data-tool="${tool}" data-tool-name="${toolInfo.name || tool}">${getToolInitials(tool)}</span>`;
615625
}).join('')
616626
: '<span class="no-detection">—</span>'}
617627
</td>
@@ -623,6 +633,64 @@ function createPathTable(paths) {
623633
`;
624634
}
625635

636+
// Setup instant tooltips for detection circles and category chips
637+
let tooltipsInitialized = false;
638+
function setupInstantTooltips() {
639+
// Only initialize once
640+
if (tooltipsInitialized) return;
641+
tooltipsInitialized = true;
642+
643+
// Create tooltip element (reuse single element)
644+
const tooltip = document.createElement('div');
645+
tooltip.className = 'detection-tooltip';
646+
document.body.appendChild(tooltip);
647+
648+
// Use event delegation for hover on detection circles and category chips
649+
document.body.addEventListener('mouseover', (e) => {
650+
const circle = e.target.closest('.detection-tool-circle');
651+
const category = e.target.closest('.path-category');
652+
653+
if (circle) {
654+
const toolName = circle.getAttribute('data-tool-name');
655+
if (toolName) {
656+
tooltip.textContent = toolName;
657+
658+
// Position tooltip above the circle
659+
const rect = circle.getBoundingClientRect();
660+
tooltip.style.left = `${rect.left + rect.width / 2}px`;
661+
tooltip.style.top = `${rect.top - 10}px`;
662+
tooltip.style.transform = 'translate(-50%, -100%)';
663+
664+
// Show immediately
665+
tooltip.classList.add('visible');
666+
}
667+
} else if (category) {
668+
const categoryTooltip = category.getAttribute('data-category-tooltip');
669+
if (categoryTooltip) {
670+
tooltip.textContent = categoryTooltip;
671+
672+
// Position tooltip above the category chip
673+
const rect = category.getBoundingClientRect();
674+
tooltip.style.left = `${rect.left + rect.width / 2}px`;
675+
tooltip.style.top = `${rect.top - 10}px`;
676+
tooltip.style.transform = 'translate(-50%, -100%)';
677+
678+
// Show immediately
679+
tooltip.classList.add('visible');
680+
}
681+
}
682+
});
683+
684+
document.body.addEventListener('mouseout', (e) => {
685+
const circle = e.target.closest('.detection-tool-circle');
686+
const category = e.target.closest('.path-category');
687+
688+
if (circle || category) {
689+
tooltip.classList.remove('visible');
690+
}
691+
});
692+
}
693+
626694
// Handle path click with modifier keys
627695
function handlePathClick(event, path) {
628696
// Check if Ctrl (Windows/Linux) or Cmd (Mac) is pressed, or if it's a middle-click
@@ -684,7 +752,7 @@ function showPathDetails(path) {
684752
</div>
685753
<div class="metadata-item">
686754
<span class="metadata-label">Category:</span>
687-
<span class="path-category category-${path.category}">${formatCategory(path.category)}</span>
755+
<span class="path-category category-${path.category}" data-category-tooltip="${categoryTooltips[path.category] || ''}">${formatCategory(path.category)}</span>
688756
</div>
689757
</div>
690758

scripts/requirements.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
PyYAML>=6.0
2+
requests>=2.31.0

0 commit comments

Comments
 (0)