diff --git a/Overlord-Server/public/assets/main.js b/Overlord-Server/public/assets/main.js index eabf941..ad58ab8 100644 --- a/Overlord-Server/public/assets/main.js +++ b/Overlord-Server/public/assets/main.js @@ -175,6 +175,7 @@ function isClientOnline(clientId) { function applyMenuSupportRules(clientId) { const platform = detectClientPlatform(clientId); const isWindows = platform === "windows"; + const isOnline = isClientOnline(clientId); const setAvailability = (btn, enabled, reason) => { if (!btn) return; @@ -188,21 +189,21 @@ function applyMenuSupportRules(clientId) { }; const hvncBtn = menu.querySelector('[data-open="Backstage"]'); - setAvailability(hvncBtn, isWindows, "Backstage is only supported on Windows clients."); + setAvailability(hvncBtn, isOnline && isWindows, isOnline ? "Backstage is only supported on Windows clients." : "Client is offline"); const webcamBtn = menu.querySelector('[data-open="webcam"]'); - setAvailability(webcamBtn, isWindows, "Webcam viewer is only supported on Windows clients."); + setAvailability(webcamBtn, isOnline && isWindows, isOnline ? "Webcam viewer is only supported on Windows clients." : "Client is offline"); const keyloggerBtn = menu.querySelector('[data-open="keylogger"]'); setAvailability( keyloggerBtn, - isWindows, - "Keylogger capture is only fully supported on Windows clients.", + isOnline && isWindows, + isOnline ? "Keylogger capture is only fully supported on Windows clients." : "Client is offline", ); const winreBtn = menu.querySelector('[data-open="winre"]'); if (winreBtn) { - setAvailability(winreBtn, isWindows, "WinRE Persistence is only supported on Windows clients."); + setAvailability(winreBtn, isOnline && isWindows, isOnline ? "WinRE Persistence is only supported on Windows clients." : "Client is offline"); const label = winreBtn.querySelector("span"); if (label) label.style.textDecoration = isWindows ? "" : "line-through"; } @@ -210,7 +211,26 @@ function applyMenuSupportRules(clientId) { const elevateBtn = menu.querySelector('[data-action="elevate"]'); if (elevateBtn) { elevateBtn.style.display = platform === "mac" ? "" : "none"; + if (platform === "mac") setAvailability(elevateBtn, isOnline, "Client is offline"); } + + setAvailability(menu.querySelector('[data-open="console"]'), isOnline, "Client is offline"); + setAvailability(menu.querySelector('[data-open="remotedesktop"]'), isOnline, "Client is offline"); + setAvailability(menu.querySelector('[data-open="voice"]'), isOnline, "Client is offline"); + setAvailability(menu.querySelector('[data-open="processes"]'), isOnline, "Client is offline"); + setAvailability(menu.querySelector('[data-open="files"]'), isOnline, "Client is offline"); + const silentExecBtn = menu.querySelector('[data-open="silent-exec"]'); + if (silentExecBtn && !silentExecBtn.classList.contains("hidden")) { + setAvailability(silentExecBtn, isOnline, "Client is offline"); + } + + ["remote-access", "monitoring", "system"].forEach(groupId => { + setAvailability(menu.querySelector(`[data-group-toggle="${groupId}"]`), isOnline, "Client is offline"); + }); + + ["ping", "reconnect", "disconnect", "uninstall"].forEach(action => { + setAvailability(menu.querySelector(`[data-action="${action}"]`), isOnline, "Client is offline"); + }); } async function loadCurrentUser() { diff --git a/Overlord-Server/public/assets/ui.js b/Overlord-Server/public/assets/ui.js index bb95310..1d9a98a 100644 --- a/Overlord-Server/public/assets/ui.js +++ b/Overlord-Server/public/assets/ui.js @@ -110,11 +110,16 @@ menuStyle.textContent = ` -webkit-user-select: none; transition: background 0.1s, color 0.1s; } -.ctx-row:hover, -.ctx-row.ctx-active { +.ctx-row:hover:not([disabled]):not([aria-disabled="true"]), +.ctx-row.ctx-active:not([disabled]):not([aria-disabled="true"]) { background: rgba(71,85,105,0.55); color: #f1f5f9; } +.ctx-row[disabled], +.ctx-row[aria-disabled="true"] { + opacity: 0.38; + cursor: not-allowed; +} .ctx-row.ctx-active .ctx-chevron { opacity: 1; } @@ -270,6 +275,7 @@ function isMobileMenu() { ctxMain.querySelectorAll(".ctx-row").forEach(rowEl => { rowEl.addEventListener("mouseenter", () => { if (isMobileMenu()) return; + if (rowEl.disabled || rowEl.getAttribute("aria-disabled") === "true") return; const groupId = rowEl.dataset.groupToggle; if (groupId) showSubmenu(groupId, rowEl); }); @@ -289,6 +295,7 @@ ctxMain.querySelectorAll(".ctx-row").forEach(rowEl => { rowEl.addEventListener("click", (e) => { const groupId = rowEl.dataset.groupToggle; if (!groupId) return; + if (rowEl.disabled || rowEl.getAttribute("aria-disabled") === "true") return; e.stopPropagation(); if (activeGroupId === groupId) { hideSubmenu(); } else { showSubmenu(groupId, rowEl); } });