From c2839091b4d66f9cadb775435128c36b59f9ad98 Mon Sep 17 00:00:00 2001 From: denys-holub Date: Tue, 27 Aug 2024 11:15:25 +0200 Subject: [PATCH 1/5] fix(frontend): hardcoded api endpoint --- internal/webui/package.json | 7 ++++--- internal/webui/src/QueryClient.tsx | 2 +- internal/webui/src/api.ts | 23 +++++++++++++++++++++ internal/webui/src/axiosInstance.ts | 18 ---------------- internal/webui/src/services/Auth/index.ts | 10 +++++++-- internal/webui/src/services/Metric/index.ts | 16 +++++++++----- internal/webui/src/services/Preset/index.ts | 16 +++++++++----- internal/webui/src/services/Source/index.ts | 22 +++++++++++++------- 8 files changed, 72 insertions(+), 42 deletions(-) create mode 100644 internal/webui/src/api.ts delete mode 100644 internal/webui/src/axiosInstance.ts diff --git a/internal/webui/package.json b/internal/webui/package.json index f3a7e865b9..612f273abb 100644 --- a/internal/webui/package.json +++ b/internal/webui/package.json @@ -7,8 +7,8 @@ "build": "react-scripts build", "test": "react-scripts test", "eject": "react-scripts eject", - "lint:ts": "eslint --ext=jsx,ts,tsx internal", - "lint:fix": "eslint --ext=jsx,ts,tsx internal --fix", + "lint:ts": "eslint --ext=jsx,ts,tsx src", + "lint:fix": "eslint --ext=jsx,ts,tsx src --fix", "lint:cypress": "eslint --no-eslintrc --ext=ts -c cypress/.eslintrc cypress/e2e", "lint:quick": "yarn lint:ts --cache" }, @@ -74,5 +74,6 @@ ] }, "main": "index.js", - "license": "MIT" + "license": "MIT", + "packageManager": "yarn@1.22.22+sha1.ac34549e6aa8e7ead463a7407e1c7390f61a6610" } diff --git a/internal/webui/src/QueryClient.tsx b/internal/webui/src/QueryClient.tsx index 3c63f57db2..7351ea6b8c 100644 --- a/internal/webui/src/QueryClient.tsx +++ b/internal/webui/src/QueryClient.tsx @@ -1,6 +1,6 @@ import { QueryClientProvider as ClientProvider, MutationCache, QueryCache, QueryClient } from "@tanstack/react-query"; +import { isUnauthorized } from "api"; import axios from "axios"; -import { isUnauthorized } from "axiosInstance"; import { useNavigate } from "react-router-dom"; import { logout } from "queries/Auth"; import { useAlert } from "utils/AlertContext"; diff --git a/internal/webui/src/api.ts b/internal/webui/src/api.ts new file mode 100644 index 0000000000..f77ddb44f3 --- /dev/null +++ b/internal/webui/src/api.ts @@ -0,0 +1,23 @@ +import axios, { AxiosError } from "axios"; +import { getToken } from "services/Token"; + +export const apiClient = () => { + const apiEndpoint = window.location.origin; + const instance = axios.create({ + baseURL: apiEndpoint, + }); + + instance.interceptors.request.use(req => { + req.headers.set("Token", getToken()); + return req; + }); + + return instance; +}; + +export const isUnauthorized = (error: AxiosError) => { + if (error.response?.status === axios.HttpStatusCode.Unauthorized) { + return true; + } + return false; +}; diff --git a/internal/webui/src/axiosInstance.ts b/internal/webui/src/axiosInstance.ts deleted file mode 100644 index 24968346c1..0000000000 --- a/internal/webui/src/axiosInstance.ts +++ /dev/null @@ -1,18 +0,0 @@ -import axios, { AxiosError } from "axios"; -import { getToken } from "services/Token"; - -export const axiosInstance = axios.create({ - baseURL: "http://localhost:8080/" -}); - -axiosInstance.interceptors.request.use(req => { - req.headers.set("Token", getToken()); - return req; -}); - -export const isUnauthorized = (error: AxiosError) => { - if (error.response?.status === axios.HttpStatusCode.Unauthorized) { - return true; - } - return false; -}; diff --git a/internal/webui/src/services/Auth/index.ts b/internal/webui/src/services/Auth/index.ts index 2b2f89e27c..9c2623676f 100644 --- a/internal/webui/src/services/Auth/index.ts +++ b/internal/webui/src/services/Auth/index.ts @@ -1,9 +1,15 @@ -import { axiosInstance } from "axiosInstance"; +import { apiClient } from "api"; +import { AxiosInstance } from "axios"; import { LoginFormValues } from "pages/LoginPage/components/LoginForm/LoginForm.types"; export default class AuthService { + private api: AxiosInstance; private static _instance: AuthService; + constructor() { + this.api = apiClient(); + } + public static getInstance(): AuthService { if (!AuthService._instance) { AuthService._instance = new AuthService(); @@ -13,7 +19,7 @@ export default class AuthService { }; public async login(data: LoginFormValues) { - return await axiosInstance.post("login", data). + return await this.api.post("/login", data). then(response => response.data); }; } diff --git a/internal/webui/src/services/Metric/index.ts b/internal/webui/src/services/Metric/index.ts index 058d875949..73da3333d5 100644 --- a/internal/webui/src/services/Metric/index.ts +++ b/internal/webui/src/services/Metric/index.ts @@ -1,11 +1,17 @@ -import { axiosInstance } from "axiosInstance"; +import { apiClient } from "api"; +import { AxiosInstance } from "axios"; import { Metrics } from "types/Metric/Metric"; import { MetricRequestBody } from "types/Metric/MetricRequestBody"; export default class MetricService { + private api: AxiosInstance; private static _instance: MetricService; + constructor() { + this.api = apiClient(); + } + public static getInstance(): MetricService { if (!MetricService._instance) { MetricService._instance = new MetricService(); @@ -15,22 +21,22 @@ export default class MetricService { }; public async getMetrics(): Promise { - return await axiosInstance.get("metric"). + return await this.api.get("/metric"). then(response => response.data); }; public async deleteMetric(data: string) { - return await axiosInstance.delete("metric", { params: { "key": data } }). + return await this.api.delete("/metric", { params: { "key": data } }). then(response => response.data); }; public async addMetric(data: MetricRequestBody) { - return await axiosInstance.post("metric", data.Data, { params: { "name": data.Name } }). + return await this.api.post("/metric", data.Data, { params: { "name": data.Name } }). then(response => response); }; public async editMetric(data: MetricRequestBody) { - return await axiosInstance.post("metric", data.Data, { params: { "name": data.Name } }). + return await this.api.post("/metric", data.Data, { params: { "name": data.Name } }). then(response => response); }; } diff --git a/internal/webui/src/services/Preset/index.ts b/internal/webui/src/services/Preset/index.ts index 49798e1ad2..f701772603 100644 --- a/internal/webui/src/services/Preset/index.ts +++ b/internal/webui/src/services/Preset/index.ts @@ -1,10 +1,16 @@ -import { axiosInstance } from "axiosInstance"; +import { apiClient } from "api"; +import { AxiosInstance } from "axios"; import { PresetRequestBody } from "types/Preset/PresetRequestBody"; export default class PresetService { + private api: AxiosInstance; private static _instance: PresetService; + constructor() { + this.api = apiClient(); + } + public static getInstance(): PresetService { if (!PresetService._instance) { PresetService._instance = new PresetService(); @@ -14,22 +20,22 @@ export default class PresetService { }; public async getPresets() { - return await axiosInstance.get("preset"). + return await this.api.get("/preset"). then(response => response.data); }; public async deletePreset(name: string) { - return await axiosInstance.delete("preset", { params: { name } }). + return await this.api.delete("/preset", { params: { name } }). then(response => response.data); }; public async addPreset(data: PresetRequestBody) { - return await axiosInstance.post("preset", data.Data, { params: { "name": data.Name } }). + return await this.api.post("/preset", data.Data, { params: { "name": data.Name } }). then(response => response); }; public async editPreset(data: PresetRequestBody) { - return await axiosInstance.post("preset", data.Data, { params: { "name": data.Name } }). + return await this.api.post("/preset", data.Data, { params: { "name": data.Name } }). then(response => response); }; }; diff --git a/internal/webui/src/services/Source/index.ts b/internal/webui/src/services/Source/index.ts index a21a68063a..b59b8e401e 100644 --- a/internal/webui/src/services/Source/index.ts +++ b/internal/webui/src/services/Source/index.ts @@ -1,10 +1,16 @@ -import { axiosInstance } from "axiosInstance"; +import { apiClient } from "api"; +import { AxiosInstance } from "axios"; import { Source } from "types/Source/Source"; import { SourceRequestBody } from "types/Source/SourceRequestBody"; export default class SourceService { + private api: AxiosInstance; private static _instance: SourceService; + constructor() { + this.api = apiClient(); + } + public static getInstance(): SourceService { if (!SourceService._instance) { SourceService._instance = new SourceService(); @@ -14,35 +20,35 @@ export default class SourceService { }; public async getSources() { - return await axiosInstance.get("source"). + return await this.api.get("/source"). then(response => response.data); }; public async deleteSource(uniqueName: string) { - return await axiosInstance.delete("source", { params: { "name": uniqueName } }). + return await this.api.delete("/source", { params: { "name": uniqueName } }). then(response => response.data); }; public async addSource(data: Source) { - return await axiosInstance.post("source", data). + return await this.api.post("/source", data). then(response => response); }; public async editSource(data: SourceRequestBody) { - return await axiosInstance.post("source", data.data, { params: { "name": data.Name } }). + return await this.api.post("/source", data.data, { params: { "name": data.Name } }). then(response => response); }; public async editSourceEnable(data: Source) { - return await axiosInstance.post("source", data, { params: { "name": data.Name } }). + return await this.api.post("/source", data, { params: { "name": data.Name } }). then(response => response); }; public async editSourceHostConfig(data: Source) { - return await axiosInstance.post("source", data, { params: { "name": data.Name } }); + return await this.api.post("/source", data, { params: { "name": data.Name } }); }; public async testSourceConnection(data: string) { - return await axiosInstance.post("test-connect", data); + return await this.api.post("/test-connect", data); }; } From c5efc731391a9a5ef81631bf0a2221d45e6cac90 Mon Sep 17 00:00:00 2001 From: denys-holub Date: Tue, 27 Aug 2024 11:58:08 +0200 Subject: [PATCH 2/5] fix(frontend): websocket url --- internal/webui/src/queries/Log/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/webui/src/queries/Log/index.ts b/internal/webui/src/queries/Log/index.ts index a5a9b16f9d..9aafb5f35b 100644 --- a/internal/webui/src/queries/Log/index.ts +++ b/internal/webui/src/queries/Log/index.ts @@ -1,7 +1,7 @@ import { useWebSocket } from "react-use-websocket/dist/lib/use-websocket"; import { getToken } from "services/Token"; -const socketUrl = "ws://localhost:8080/log"; +const socketUrl = `ws://${window.location.origin}/log`; const token = getToken(); export const useLogs = () => useWebSocket(socketUrl, { From 76441949dc713212522fce538e497f66247f0699 Mon Sep 17 00:00:00 2001 From: denys-holub Date: Tue, 27 Aug 2024 12:26:22 +0200 Subject: [PATCH 3/5] fix(frontend): websocket url --- internal/webui/src/queries/Log/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/webui/src/queries/Log/index.ts b/internal/webui/src/queries/Log/index.ts index 9aafb5f35b..654f1e6545 100644 --- a/internal/webui/src/queries/Log/index.ts +++ b/internal/webui/src/queries/Log/index.ts @@ -1,7 +1,7 @@ import { useWebSocket } from "react-use-websocket/dist/lib/use-websocket"; import { getToken } from "services/Token"; -const socketUrl = `ws://${window.location.origin}/log`; +const socketUrl = `ws://${window.location.host}/log`; const token = getToken(); export const useLogs = () => useWebSocket(socketUrl, { From e647dd97d69c066c8880a9d095800470b9c9f892 Mon Sep 17 00:00:00 2001 From: denys-holub Date: Tue, 27 Aug 2024 12:37:32 +0200 Subject: [PATCH 4/5] chore(frontend): define socket protocol --- internal/webui/src/queries/Log/index.ts | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/internal/webui/src/queries/Log/index.ts b/internal/webui/src/queries/Log/index.ts index 654f1e6545..4d3d53cbc3 100644 --- a/internal/webui/src/queries/Log/index.ts +++ b/internal/webui/src/queries/Log/index.ts @@ -1,11 +1,16 @@ import { useWebSocket } from "react-use-websocket/dist/lib/use-websocket"; import { getToken } from "services/Token"; -const socketUrl = `ws://${window.location.host}/log`; -const token = getToken(); - -export const useLogs = () => useWebSocket(socketUrl, { - queryParams: { - "Token": token ? token : "" - } -}); +export const useLogs = () => { + const socketProtocol = window.location.protocol === "https:" ? "wss://" : "ws://"; + const token = getToken() || ""; + + return useWebSocket( + `${socketProtocol}${window.location.host}/log`, + { + queryParams: { + "Token": token, + }, + }, + ); +}; From eb25b61d99acb1bb0391f5756594dafae7babb06 Mon Sep 17 00:00:00 2001 From: denys-holub Date: Tue, 27 Aug 2024 13:00:34 +0200 Subject: [PATCH 5/5] fix(frontend): endless alert --- internal/webui/src/pages/LogsPage/components/Logs.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/webui/src/pages/LogsPage/components/Logs.tsx b/internal/webui/src/pages/LogsPage/components/Logs.tsx index f3eb0bb9a6..db9f9634dc 100644 --- a/internal/webui/src/pages/LogsPage/components/Logs.tsx +++ b/internal/webui/src/pages/LogsPage/components/Logs.tsx @@ -33,7 +33,7 @@ export const Logs = () => { callAlert("error", "Connection uninstantiated"); break; } - }, [readyState, callAlert]); + }, [readyState]); // eslint-disable-line return (