From f27c2f4eb283f7dfb693911796e40b0a72aa127e Mon Sep 17 00:00:00 2001 From: Alex P Date: Sat, 11 Oct 2025 00:17:49 +0300 Subject: [PATCH] fix: prevent RPC calls before session approval Issue: - RPC calls (getVideoState, getKeyboardLedState, getKeyDownState) were being made immediately when RPC data channel opened, before permissions were granted - This caused "Permission denied" errors in console for pending/queued sessions - Sessions waiting for nickname or approval were triggering permission errors Solution: - Added currentMode checks to guard RPC initialization calls - Only make RPC calls when session is in "primary" or "observer" mode - Skip RPC calls for "pending" or "queued" sessions Result: No more permission errors before session approval --- ui/src/routes/devices.$id.tsx | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/ui/src/routes/devices.$id.tsx b/ui/src/routes/devices.$id.tsx index 39da6092..0a08196e 100644 --- a/ui/src/routes/devices.$id.tsx +++ b/ui/src/routes/devices.$id.tsx @@ -765,19 +765,21 @@ export default function KvmIdRoute() { useEffect(() => { if (rpcDataChannel?.readyState !== "open") return; + if (currentMode === "pending" || currentMode === "queued") return; + send("getVideoState", {}, (resp: JsonRpcResponse) => { if ("error" in resp) return; const hdmiState = resp.result as Parameters[0]; setHdmiState(hdmiState); }); - }, [rpcDataChannel?.readyState, send, setHdmiState]); + }, [rpcDataChannel?.readyState, currentMode, send, setHdmiState]); const [needLedState, setNeedLedState] = useState(true); - // request keyboard led state from the device useEffect(() => { if (rpcDataChannel?.readyState !== "open") return; if (!needLedState) return; + if (currentMode === "pending" || currentMode === "queued") return; send("getKeyboardLedState", {}, (resp: JsonRpcResponse) => { if ("error" in resp) { @@ -789,20 +791,18 @@ export default function KvmIdRoute() { } setNeedLedState(false); }); - }, [rpcDataChannel?.readyState, send, setKeyboardLedState, keyboardLedState, needLedState]); + }, [rpcDataChannel?.readyState, send, setKeyboardLedState, keyboardLedState, needLedState, currentMode]); const [needKeyDownState, setNeedKeyDownState] = useState(true); - // request keyboard key down state from the device useEffect(() => { if (rpcDataChannel?.readyState !== "open") return; if (!needKeyDownState) return; + if (currentMode === "pending" || currentMode === "queued") return; send("getKeyDownState", {}, (resp: JsonRpcResponse) => { if ("error" in resp) { - // -32601 means the method is not supported if (resp.error.code === RpcMethodNotFound) { - // if we don't support key down state, we know key press is also not available console.warn("Failed to get key down state, switching to old-school", resp.error); setHidRpcDisabled(true); } else { @@ -814,7 +814,7 @@ export default function KvmIdRoute() { } setNeedKeyDownState(false); }); - }, [keysDownState, needKeyDownState, rpcDataChannel?.readyState, send, setKeysDownState, setHidRpcDisabled]); + }, [keysDownState, needKeyDownState, rpcDataChannel?.readyState, send, setKeysDownState, setHidRpcDisabled, currentMode]); // When the update is successful, we need to refresh the client javascript and show a success modal useEffect(() => {