From e40f7ffb986b0324a0fe965ff2117978b75f18ac Mon Sep 17 00:00:00 2001 From: Rezky Hamid Date: Sun, 3 May 2026 15:00:43 +0700 Subject: [PATCH] fix(mitm): gate sudo prompts on server platform (#822) --- .../components/AntigravityToolCard.js | 11 ++++--- .../cli-tools/components/MitmServerCard.js | 33 +++++++++---------- .../cli-tools/components/MitmToolCard.js | 5 +-- .../dashboard/mitm/MitmPageClient.js | 1 + .../api/cli-tools/antigravity-mitm/route.js | 18 +++++++--- src/mitm/dns/dnsConfig.js | 16 +++++++++ src/mitm/manager.js | 15 +++++---- 7 files changed, 62 insertions(+), 37 deletions(-) diff --git a/src/app/(dashboard)/dashboard/cli-tools/components/AntigravityToolCard.js b/src/app/(dashboard)/dashboard/cli-tools/components/AntigravityToolCard.js index db3427a9..d449347e 100644 --- a/src/app/(dashboard)/dashboard/cli-tools/components/AntigravityToolCard.js +++ b/src/app/(dashboard)/dashboard/cli-tools/components/AntigravityToolCard.js @@ -88,11 +88,12 @@ export default function AntigravityToolCard({ } }; - // Windows uses UAC dialog, no sudo needed - const isWindows = typeof navigator !== "undefined" && navigator.userAgent?.includes("Windows"); + // MITM elevation is decided by the server OS, not by this browser's OS. + const serverIsWindows = status?.isWin === true; + const canRunWithoutPassword = serverIsWindows || status?.hasCachedPassword || status?.needsSudoPassword === false; const handleStart = () => { - if (isWindows || status?.hasCachedPassword) { + if (canRunWithoutPassword) { doStart(""); } else { setShowPasswordModal(true); @@ -101,7 +102,7 @@ export default function AntigravityToolCard({ }; const handleStop = () => { - if (isWindows || status?.hasCachedPassword) { + if (canRunWithoutPassword) { doStop(""); } else { setShowPasswordModal(true); @@ -385,7 +386,7 @@ export default function AntigravityToolCard({ )} {/* Windows admin warning */} - {!isRunning && isWindows && ( + {!isRunning && serverIsWindows && (
warning Windows: Run terminal (9Router) as Administrator to enable MITM diff --git a/src/app/(dashboard)/dashboard/cli-tools/components/MitmServerCard.js b/src/app/(dashboard)/dashboard/cli-tools/components/MitmServerCard.js index 182ac520..c171ad12 100644 --- a/src/app/(dashboard)/dashboard/cli-tools/components/MitmServerCard.js +++ b/src/app/(dashboard)/dashboard/cli-tools/components/MitmServerCard.js @@ -1,6 +1,6 @@ "use client"; -import { useState, useEffect } from "react"; +import { useState, useEffect, useCallback } from "react"; import { Card, Button, Badge, Input } from "@/shared/components"; const DEFAULT_MITM_ROUTER_BASE = "http://localhost:20128"; @@ -14,26 +14,17 @@ export default function MitmServerCard({ apiKeys, cloudEnabled, onStatusChange } const [loading, setLoading] = useState(false); const [showPasswordModal, setShowPasswordModal] = useState(false); const [sudoPassword, setSudoPassword] = useState(""); - const [selectedApiKey, setSelectedApiKey] = useState(""); + const [selectedApiKey, setSelectedApiKey] = useState(() => apiKeys?.[0]?.key || ""); const [pendingAction, setPendingAction] = useState(null); const [modalError, setModalError] = useState(null); const [actionError, setActionError] = useState(null); const [mitmRouterBaseUrl, setMitmRouterBaseUrl] = useState(DEFAULT_MITM_ROUTER_BASE); - const isWindows = typeof navigator !== "undefined" && navigator.userAgent?.includes("Windows"); + const serverIsWindows = status?.isWin === true; + const canRunWithoutPassword = serverIsWindows || status?.hasCachedPassword || status?.needsSudoPassword === false; const isAdmin = status?.isAdmin !== false; - useEffect(() => { - if (apiKeys?.length > 0 && !selectedApiKey) { - setSelectedApiKey(apiKeys[0].key); - } - }, [apiKeys, selectedApiKey]); - - useEffect(() => { - fetchStatus(); - }, []); - - const fetchStatus = async () => { + const fetchStatus = useCallback(async () => { try { const res = await fetch("/api/cli-tools/antigravity-mitm"); if (res.ok) { @@ -47,11 +38,17 @@ export default function MitmServerCard({ apiKeys, cloudEnabled, onStatusChange } } catch { setStatus({ running: false, certExists: false, dnsStatus: {} }); } - }; + }, [onStatusChange]); + + useEffect(() => { + queueMicrotask(() => { + fetchStatus(); + }); + }, [fetchStatus]); const handleAction = (action) => { setActionError(null); - if (isWindows || status?.hasCachedPassword) { + if (canRunWithoutPassword) { doAction(action, ""); } else { setPendingAction(action); @@ -219,7 +216,7 @@ export default function MitmServerCard({ apiKeys, cloudEnabled, onStatusChange } ) : (