From 44ea0201b176cbc11fdad1237d00cc5e657ce82a Mon Sep 17 00:00:00 2001 From: Adam Shiervani Date: Fri, 21 Feb 2025 10:16:02 +0100 Subject: [PATCH] refactor(ui): Remove SIGNAL_API env & Rename to DEVICE_API to make clear distinction between CLOUD_API and DEVICE_API. --- ui/.env.cloud-development | 2 +- ui/.env.cloud-production | 2 +- ui/.env.cloud-staging | 2 +- ui/.env.device | 5 +---- ui/src/components/Header.tsx | 4 ++-- ui/src/components/MountMediaDialog.tsx | 4 ++-- ui/src/components/sidebar/settings.tsx | 4 ++-- ui/src/routes/adopt.tsx | 4 ++-- ui/src/routes/devices.$id.tsx | 16 +++++++++------- ui/src/routes/login-local.tsx | 8 ++++---- ui/src/routes/welcome-local.mode.tsx | 6 +++--- ui/src/routes/welcome-local.password.tsx | 6 +++--- ui/src/routes/welcome-local.tsx | 4 ++-- ui/src/ui.config.ts | 4 +++- 14 files changed, 36 insertions(+), 35 deletions(-) diff --git a/ui/.env.cloud-development b/ui/.env.cloud-development index f46c09a..471e280 100644 --- a/ui/.env.cloud-development +++ b/ui/.env.cloud-development @@ -1,4 +1,4 @@ -# No need for VITE_CLOUD_APP or VITE_SIGNAL_API, it's only needed for the device build +# No need for VITE_CLOUD_APP it's only needed for the device build # We use this for all the cloud API requests from the browser VITE_CLOUD_API=http://localhost:3000 diff --git a/ui/.env.cloud-production b/ui/.env.cloud-production index c928175..d9895d2 100644 --- a/ui/.env.cloud-production +++ b/ui/.env.cloud-production @@ -1,4 +1,4 @@ -# No need for VITE_CLOUD_APP or VITE_SIGNAL_API, it's only needed for the device build +# No need for VITE_CLOUD_APP it's only needed for the device build # We use this for all the cloud API requests from the browser VITE_CLOUD_API=https://api.jetkvm.com diff --git a/ui/.env.cloud-staging b/ui/.env.cloud-staging index 3f83839..bc5c14c 100644 --- a/ui/.env.cloud-staging +++ b/ui/.env.cloud-staging @@ -1,4 +1,4 @@ -# No need for VITE_SIGNAL_API or VITE_CLOUD_APP it's only needed for the device build +# No need for VITE_CLOUD_APP it's only needed for the device build # We use this for all the cloud API requests from the browser VITE_CLOUD_API=https://staging-api.jetkvm.com diff --git a/ui/.env.device b/ui/.env.device index ebc9618..252fac4 100644 --- a/ui/.env.device +++ b/ui/.env.device @@ -1,5 +1,2 @@ -# Uses the KVM device's IP address as the signal API endpoint -VITE_SIGNAL_API= - # Used in settings page to know where to link to when user wants to adopt a device to the cloud -VITE_CLOUD_APP=https://app.jetkvm.com +VITE_CLOUD_APP=http://localhost:5173 diff --git a/ui/src/components/Header.tsx b/ui/src/components/Header.tsx index e90fad7..7485361 100644 --- a/ui/src/components/Header.tsx +++ b/ui/src/components/Header.tsx @@ -14,7 +14,7 @@ import PeerConnectionStatusCard from "@components/PeerConnectionStatusCard"; import api from "../api"; import { isOnDevice } from "../main"; import { Button, LinkButton } from "./Button"; -import { CLOUD_API, SIGNAL_API } from "@/ui.config"; +import { CLOUD_API, DEVICE_API } from "@/ui.config"; interface NavbarProps { isLoggedIn: boolean; @@ -38,7 +38,7 @@ export default function DashboardNavbar({ const navigate = useNavigate(); const onLogout = useCallback(async () => { const logoutUrl = isOnDevice - ? `${SIGNAL_API}/auth/logout` + ? `${DEVICE_API}/auth/logout` : `${CLOUD_API}/logout`; const res = await api.POST(logoutUrl); if (!res.ok) return; diff --git a/ui/src/components/MountMediaDialog.tsx b/ui/src/components/MountMediaDialog.tsx index 4021f76..892340b 100644 --- a/ui/src/components/MountMediaDialog.tsx +++ b/ui/src/components/MountMediaDialog.tsx @@ -35,7 +35,7 @@ import { ExclamationTriangleIcon } from "@heroicons/react/20/solid"; import notifications from "../notifications"; import Fieldset from "./Fieldset"; import { isOnDevice } from "../main"; -import { SIGNAL_API } from "@/ui.config"; +import { DEVICE_API } from "@/ui.config"; export default function MountMediaModal({ open, @@ -1120,7 +1120,7 @@ function UploadFileView({ alreadyUploadedBytes: number, dataChannel: string, ) { - const uploadUrl = `${SIGNAL_API}/storage/upload?uploadId=${dataChannel}`; + const uploadUrl = `${DEVICE_API}/storage/upload?uploadId=${dataChannel}`; const xhr = new XMLHttpRequest(); xhr.open("POST", uploadUrl, true); diff --git a/ui/src/components/sidebar/settings.tsx b/ui/src/components/sidebar/settings.tsx index b200e71..2ce897d 100644 --- a/ui/src/components/sidebar/settings.tsx +++ b/ui/src/components/sidebar/settings.tsx @@ -26,7 +26,7 @@ import LocalAuthPasswordDialog from "@/components/LocalAuthPasswordDialog"; import { LocalDevice } from "@routes/devices.$id"; import { useRevalidator } from "react-router-dom"; import { ShieldCheckIcon } from "@heroicons/react/20/solid"; -import { CLOUD_APP, SIGNAL_API } from "@/ui.config"; +import { CLOUD_APP, DEVICE_API } from "@/ui.config"; import { InputFieldWithLabel } from "../InputField"; export function SettingsItem({ @@ -421,7 +421,7 @@ export default function SettingsSidebar() { const getDevice = useCallback(async () => { try { const status = await api - .GET(`${SIGNAL_API}/device`) + .GET(`${DEVICE_API}/device`) .then(res => res.json() as Promise); setLocalDevice(status); } catch (error) { diff --git a/ui/src/routes/adopt.tsx b/ui/src/routes/adopt.tsx index 88191a7..2aacf44 100644 --- a/ui/src/routes/adopt.tsx +++ b/ui/src/routes/adopt.tsx @@ -1,6 +1,6 @@ import { LoaderFunctionArgs, redirect } from "react-router-dom"; import api from "../api"; -import { CLOUD_APP, SIGNAL_API } from "@/ui.config"; +import { CLOUD_APP, DEVICE_API } from "@/ui.config"; const loader = async ({ request }: LoaderFunctionArgs) => { const url = new URL(request.url); @@ -11,7 +11,7 @@ const loader = async ({ request }: LoaderFunctionArgs) => { const oidcGoogle = searchParams.get("oidcGoogle"); const clientId = searchParams.get("clientId"); - const res = await api.POST(`${SIGNAL_API}/cloud/register`, { + const res = await api.POST(`${DEVICE_API}/cloud/register`, { token: tempToken, oidcGoogle, clientId, diff --git a/ui/src/routes/devices.$id.tsx b/ui/src/routes/devices.$id.tsx index 10ae0bc..bf589ef 100644 --- a/ui/src/routes/devices.$id.tsx +++ b/ui/src/routes/devices.$id.tsx @@ -36,7 +36,7 @@ import { DeviceStatus } from "./welcome-local"; import FocusTrap from "focus-trap-react"; import OtherSessionConnectedModal from "@/components/OtherSessionConnectedModal"; import Terminal from "@components/Terminal"; -import { CLOUD_API, SIGNAL_API } from "@/ui.config"; +import { CLOUD_API, DEVICE_API } from "@/ui.config"; interface LocalLoaderResp { authMode: "password" | "noPassword" | null; @@ -57,12 +57,12 @@ export interface LocalDevice { const deviceLoader = async () => { const res = await api - .GET(`${SIGNAL_API}/device/status`) + .GET(`${DEVICE_API}/device/status`) .then(res => res.json() as Promise); if (!res.isSetup) return redirect("/welcome"); - const deviceRes = await api.GET(`${SIGNAL_API}/device`); + const deviceRes = await api.GET(`${DEVICE_API}/device`); if (deviceRes.status === 401) return redirect("/login-local"); if (deviceRes.ok) { const device = (await deviceRes.json()) as LocalDevice; @@ -78,9 +78,7 @@ const cloudLoader = async (params: Params): Promise => const iceResp = await api.POST(`${CLOUD_API}/webrtc/ice_config`); const iceConfig = await iceResp.json(); - const deviceResp = await api.GET( - `${CLOUD_API}/devices/${params.id}`, - ); + const deviceResp = await api.GET(`${CLOUD_API}/devices/${params.id}`); if (!deviceResp.ok) { if (deviceResp.status === 404) { @@ -143,7 +141,11 @@ export default function KvmIdRoute() { try { const sd = btoa(JSON.stringify(pc.localDescription)); - const res = await api.POST(`${SIGNAL_API}/webrtc/session`, { + + const sessionUrl = isOnDevice + ? `${DEVICE_API}/webrtc/session` + : `${CLOUD_API}/webrtc/session`; + const res = await api.POST(sessionUrl, { sd, // When on device, we don't need to specify the device id, as it's already known ...(isOnDevice ? {} : { id: params.id }), diff --git a/ui/src/routes/login-local.tsx b/ui/src/routes/login-local.tsx index ff34995..17e19b4 100644 --- a/ui/src/routes/login-local.tsx +++ b/ui/src/routes/login-local.tsx @@ -12,16 +12,16 @@ import LogoWhiteIcon from "@/assets/logo-white.svg"; import api from "../api"; import { DeviceStatus } from "./welcome-local"; import ExtLink from "../components/ExtLink"; -import { SIGNAL_API } from "@/ui.config"; +import { DEVICE_API } from "@/ui.config"; const loader = async () => { const res = await api - .GET(`${SIGNAL_API}/device/status`) + .GET(`${DEVICE_API}/device/status`) .then(res => res.json() as Promise); if (!res.isSetup) return redirect("/welcome"); - const deviceRes = await api.GET(`${SIGNAL_API}/device`); + const deviceRes = await api.GET(`${DEVICE_API}/device`); if (deviceRes.ok) return redirect("/"); return null; }; @@ -32,7 +32,7 @@ const action = async ({ request }: ActionFunctionArgs) => { try { const response = await api.POST( - `${SIGNAL_API}/auth/login-local`, + `${DEVICE_API}/auth/login-local`, { password, }, diff --git a/ui/src/routes/welcome-local.mode.tsx b/ui/src/routes/welcome-local.mode.tsx index 0bf83ae..3ea54a7 100644 --- a/ui/src/routes/welcome-local.mode.tsx +++ b/ui/src/routes/welcome-local.mode.tsx @@ -9,11 +9,11 @@ import LogoWhiteIcon from "@/assets/logo-white.svg"; import { cx } from "../cva.config"; import api from "../api"; import { DeviceStatus } from "./welcome-local"; -import { SIGNAL_API } from "@/ui.config"; +import { DEVICE_API } from "@/ui.config"; const loader = async () => { const res = await api - .GET(`${SIGNAL_API}/device/status`) + .GET(`${DEVICE_API}/device/status`) .then(res => res.json() as Promise); if (res.isSetup) return redirect("/login-local"); @@ -31,7 +31,7 @@ const action = async ({ request }: ActionFunctionArgs) => { if (localAuthMode === "noPassword") { try { - await api.POST(`${SIGNAL_API}/device/setup`, { + await api.POST(`${DEVICE_API}/device/setup`, { localAuthMode, }); return redirect("/"); diff --git a/ui/src/routes/welcome-local.password.tsx b/ui/src/routes/welcome-local.password.tsx index 1ccbef3..0d6542b 100644 --- a/ui/src/routes/welcome-local.password.tsx +++ b/ui/src/routes/welcome-local.password.tsx @@ -10,11 +10,11 @@ import LogoBlueIcon from "@/assets/logo-blue.png"; import LogoWhiteIcon from "@/assets/logo-white.svg"; import api from "../api"; import { DeviceStatus } from "./welcome-local"; -import { SIGNAL_API } from "@/ui.config"; +import { DEVICE_API } from "@/ui.config"; const loader = async () => { const res = await api - .GET(`${SIGNAL_API}/device/status`) + .GET(`${DEVICE_API}/device/status`) .then(res => res.json() as Promise); if (res.isSetup) return redirect("/login-local"); @@ -31,7 +31,7 @@ const action = async ({ request }: ActionFunctionArgs) => { } try { - const response = await api.POST(`${SIGNAL_API}/device/setup`, { + const response = await api.POST(`${DEVICE_API}/device/setup`, { localAuthMode: "password", password, }); diff --git a/ui/src/routes/welcome-local.tsx b/ui/src/routes/welcome-local.tsx index dcb2e0d..9ce6203 100644 --- a/ui/src/routes/welcome-local.tsx +++ b/ui/src/routes/welcome-local.tsx @@ -9,7 +9,7 @@ import LogoMark from "@/assets/logo-mark.png"; import { cx } from "cva"; import api from "../api"; import { redirect } from "react-router-dom"; -import { SIGNAL_API } from "@/ui.config"; +import { DEVICE_API } from "@/ui.config"; export interface DeviceStatus { isSetup: boolean; @@ -17,7 +17,7 @@ export interface DeviceStatus { const loader = async () => { const res = await api - .GET(`${SIGNAL_API}/device/status`) + .GET(`${DEVICE_API}/device/status`) .then(res => res.json() as Promise); if (res.isSetup) return redirect("/login-local"); diff --git a/ui/src/ui.config.ts b/ui/src/ui.config.ts index 43ab31d..d82a6da 100644 --- a/ui/src/ui.config.ts +++ b/ui/src/ui.config.ts @@ -1,3 +1,5 @@ export const CLOUD_API = import.meta.env.VITE_CLOUD_API; export const CLOUD_APP = import.meta.env.VITE_CLOUD_APP; -export const SIGNAL_API = import.meta.env.VITE_SIGNAL_API; + +// In device mode, an empty string uses the current hostname (the JetKVM device's IP) as the API endpoint +export const DEVICE_API = "";