+
+
+
+
+
+ {authMode === "password" ? (
+ {
+ navigateTo("./local-auth", { state: { init: "deletePassword" } });
+ }}
+ />
+ ) : (
+ {
+ navigateTo("./local-auth", { state: { init: "createPassword" } });
+ }}
+ />
+ )}
+
+
+ {authMode === "password" && (
+
+ {
+ navigateTo("./local-auth", { state: { init: "updatePassword" } });
+ }}
+ />
+
+ )}
+
+
+
+
+
+ {isOnDevice && (
+ <>
+
+ {!isAdopted && (
+ <>
+
+ {
+ const value = e.target.value;
+ setSelectedUrlOption(value);
+ }}
+ options={cloudProviders ?? []}
+ />
+
+
+ {selectedUrlOption === "custom" && (
+
+ setCloudUrl(e.target.value)}
+ placeholder="https://api.example.com"
+ />
+
+ )}
+ >
+ )}
+
+ {/*
+ We do the harcoding here to avoid flickering when the default Cloud URL being fetched.
+ I've tried to avoid harcoding api.jetkvm.com, but it's the only reasonable way I could think of to avoid flickering for now.
+ */}
+ {selectedUrlOption === (defaultCloudUrl || "https://api.jetkvm.com") && (
+
+
+
+
+
+
+ Cloud Security
+
+
+
+ End-to-end encryption using WebRTC (DTLS and SRTP)
+ Zero Trust security model
+ OIDC (OpenID Connect) authentication
+ All streams encrypted in transit
+
+
+
+
+ All cloud components are open-source and available on{" "}
+
+ GitHub
+
+ .
+
+
+
+
+
+
+
+
+
+
+ )}
+
+ {!isAdopted ? (
+
+ onCloudAdoptClick(cloudUrl)}
+ size="SM"
+ theme="primary"
+ text="Adopt KVM to Cloud"
+ />
+
+ ) : (
+
+
+
+ Your device is adopted to JetKVM Cloud
+
+
+ {
+ if (deviceId) {
+ if (
+ window.confirm(
+ "Are you sure you want to de-register this device?",
+ )
+ ) {
+ deregisterDevice();
+ }
+ } else {
+ notifications.error("No device ID available");
+ }
+ }}
+ />
+
+
+
+ )}
+
+ >
+ )}
+
+
+ );
+}
diff --git a/ui/src/routes/devices.$id.settings.security.local-auth.tsx b/ui/src/routes/devices.$id.settings.access.local-auth.tsx
similarity index 99%
rename from ui/src/routes/devices.$id.settings.security.local-auth.tsx
rename to ui/src/routes/devices.$id.settings.access.local-auth.tsx
index 702bfba..4f07bd8 100644
--- a/ui/src/routes/devices.$id.settings.security.local-auth.tsx
+++ b/ui/src/routes/devices.$id.settings.access.local-auth.tsx
@@ -6,7 +6,7 @@ import { useLocalAuthModalStore } from "@/hooks/stores";
import { useLocation, useRevalidator } from "react-router-dom";
import { useDeviceUiNavigation } from "@/hooks/useAppNavigation";
-export default function LocalAuthRoute() {
+export default function SecurityAccessLocalAuthRoute() {
const { setModalView } = useLocalAuthModalStore();
const { navigateTo } = useDeviceUiNavigation();
const location = useLocation();
diff --git a/ui/src/routes/devices.$id.settings.advanced.tsx b/ui/src/routes/devices.$id.settings.advanced.tsx
index ae8996e..a46c8c4 100644
--- a/ui/src/routes/devices.$id.settings.advanced.tsx
+++ b/ui/src/routes/devices.$id.settings.advanced.tsx
@@ -8,7 +8,6 @@ import { useCallback, useState, useEffect } from "react";
import notifications from "../notifications";
import { TextAreaWithLabel } from "../components/TextArea";
import { isOnDevice } from "../main";
-import { InputFieldWithLabel } from "../components/InputField";
import { Button } from "../components/Button";
import { useSettingsStore } from "../hooks/stores";
import { GridCard } from "@components/Card";
@@ -16,16 +15,11 @@ import { GridCard } from "@components/Card";
export default function SettingsAdvancedRoute() {
const [send] = useJsonRpc();
- const [cloudUrl, setCloudUrl] = useState("");
const [sshKey, setSSHKey] = useState("");
const setDeveloperMode = useSettingsStore(state => state.setDeveloperMode);
const settings = useSettingsStore();
useEffect(() => {
- send("getCloudUrl", {}, resp => {
- if ("error" in resp) return;
- setCloudUrl(resp.result as string);
- });
send("getDevModeState", {}, resp => {
if ("error" in resp) return;
@@ -51,12 +45,6 @@ export default function SettingsAdvancedRoute() {
});
}, [send]);
- const getCloudUrl = useCallback(() => {
- send("getCloudUrl", {}, resp => {
- if ("error" in resp) return;
- setCloudUrl(resp.result as string);
- });
- }, [send]);
const handleUsbEmulationToggle = useCallback(
(enabled: boolean) => {
@@ -74,35 +62,6 @@ export default function SettingsAdvancedRoute() {
[getUsbEmulationState, send],
);
- const handleCloudUrlChange = useCallback(
- (url: string) => {
- send("setCloudUrl", { url }, resp => {
- if ("error" in resp) {
- notifications.error(
- `Failed to update cloud URL: ${resp.error.data || "Unknown error"}`,
- );
- return;
- }
- getCloudUrl();
- notifications.success("Cloud URL updated successfully");
- });
- },
- [send, getCloudUrl],
- );
-
- const handleResetCloudUrl = useCallback(() => {
- send("resetCloudUrl", {}, resp => {
- if ("error" in resp) {
- notifications.error(
- `Failed to reset cloud URL: ${resp.error.data || "Unknown error"}`,
- );
- return;
- }
- getCloudUrl();
- notifications.success("Cloud URL reset to default successfully");
- });
- }, [send, getCloudUrl]);
-
const handleResetConfig = useCallback(() => {
send("resetConfig", {}, resp => {
if ("error" in resp) {
@@ -244,37 +203,6 @@ export default function SettingsAdvancedRoute() {
)}
- {isOnDevice && settings.developerMode && (
-
-
-
-
setCloudUrl(e.target.value)}
- placeholder="https://api.jetkvm.com"
- />
-
-
- handleCloudUrlChange(cloudUrl)}
- />
-
-
-
- )}
{isOnDevice && settings.developerMode && (
(null);
- const [isAdopted, setAdopted] = useState(false);
const [currentVersions, setCurrentVersions] = useState<{
appVersion: string;
systemVersion: string;
} | null>(null);
- const getCloudState = useCallback(() => {
- send("getCloudState", {}, resp => {
- if ("error" in resp) return console.error(resp.error);
- const cloudState = resp.result as { connected: boolean };
- setAdopted(cloudState.connected);
- });
- }, [send]);
-
- const deregisterDevice = async () => {
- send("deregisterDevice", {}, resp => {
- if ("error" in resp) {
- notifications.error(
- `Failed to de-register device: ${resp.error.data || "Unknown error"}`,
- );
- return;
- }
- getCloudState();
- return;
- });
- };
-
const getCurrentVersions = useCallback(() => {
send("getUpdateStatus", {}, resp => {
if ("error" in resp) return;
@@ -61,12 +34,6 @@ export default function SettingsGeneralRoute() {
useEffect(() => {
getCurrentVersions();
- getCloudState();
- send("getDeviceID", {}, async resp => {
- if ("error" in resp) return console.error(resp.error);
- setDeviceId(resp.result as string);
- });
-
send("getAutoUpdateState", {}, resp => {
if ("error" in resp) return;
setAutoUpdate(resp.result as boolean);
@@ -76,7 +43,7 @@ export default function SettingsGeneralRoute() {
if ("error" in resp) return;
setDevChannel(resp.result as boolean);
});
- }, [getCurrentVersions, getCloudState, send]);
+ }, [getCurrentVersions, send]);
const handleAutoUpdateChange = (enabled: boolean) => {
send("setAutoUpdateState", { enabled }, resp => {
@@ -164,108 +131,6 @@ export default function SettingsGeneralRoute() {