diff --git a/src/App.tsx b/src/App.tsx index 1ba71bc5..945850dd 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -3,8 +3,10 @@ import AppRouter from "AppRouter"; import Onboarding from "modules/onboarding/components/Onboarding"; import { useEffect } from "react"; import Modal from "react-modal"; +import { ToastContainer } from "react-toastify"; import { isIP, isBrowserEnv, isDesktopEnv } from "shared/helpers/utils"; +import Login from "./modules/onboarding/components/Login"; import useSettingStore, { getBackendUrl } from "./shared/store/setting"; Modal.setAppElement("#root"); @@ -58,11 +60,12 @@ function App() { })(); }, [isSettingStoreHydrated]); - if (!isBrowser) { - return } />; - } - - return ; + return ( + <> + {isBrowser ? } /> : } />} + + + ); } export default App; diff --git a/src/AppRouter.tsx b/src/AppRouter.tsx index d302daea..45260e3b 100644 --- a/src/AppRouter.tsx +++ b/src/AppRouter.tsx @@ -8,7 +8,6 @@ import Service from "modules/service/components/Service"; import ServiceDetail from "modules/service-detail/components/ServiceDetail"; import Settings from "modules/settings/components/Settings"; import { Route, BrowserRouter as Router, Routes } from "react-router-dom"; -import { ToastContainer } from "react-toastify"; import NotFound from "shared/components/NotFound"; import "react-toastify/dist/ReactToastify.css"; @@ -36,7 +35,6 @@ const AppRouter = () => { } /> - ); }; diff --git a/src/modules/onboarding/components/Login.tsx b/src/modules/onboarding/components/Login.tsx new file mode 100644 index 00000000..1ec4aa86 --- /dev/null +++ b/src/modules/onboarding/components/Login.tsx @@ -0,0 +1,58 @@ +import type { FormEvent, ReactElement } from "react"; +import { useState } from "react"; +import { toast } from "react-toastify"; + +import apiAuthd from "../../../shared/api/authd"; +import PrimaryButton from "../../../shared/components/PrimaryButton"; +import useSettingStore from "../../../shared/store/setting"; + +const Login = ({ redirectTo }: { redirectTo: ReactElement }) => { + const [isAuthenticated, setIsAuthenticated] = useState(false); + const setApiKey = useSettingStore((state) => state.setApiKey); + + const onSubmit = async (e: FormEvent) => { + e.preventDefault(); + const target = e.target as HTMLFormElement & { + user: { value: string }; + password: { value: string }; + }; + try { + const user = target.user.value; + const password = target.password.value; + await apiAuthd() + .get(`/login?user=${user}&pass=${password}`) + .then((res) => { + console.log("res", res); + setIsAuthenticated(true); + setApiKey(res.data); + }); + } catch (error: any) { + toast.error(error.message, { toastId: "login-error" }); + } finally { + target.reset(); + } + }; + + if (isAuthenticated) { + return redirectTo; + } + + return ( +
+

Login

+
+ + + Submit +
+
+ ); +}; + +export default Login; diff --git a/src/shared/api/authd.ts b/src/shared/api/authd.ts new file mode 100644 index 00000000..e96e3a3c --- /dev/null +++ b/src/shared/api/authd.ts @@ -0,0 +1,23 @@ +import axios from "axios"; + +import { isProxyEnabled } from "../helpers/utils"; +import useSettingStore from "../store/setting"; + +const apiAuthd = () => { + const isIP = useSettingStore.getState().isIP; + const headers = { "Content-Type": "application/json" }; + let baseURL; + if (isProxyEnabled()) { + if (isIP) { + baseURL = `${useSettingStore.getState().backendUrl}authd/auth`; + } else { + baseURL = `${window.location.protocol}//authd.${window.location.host}/auth`; + } + } + return axios.create({ + baseURL, + headers, + }); +}; + +export default apiAuthd; diff --git a/src/shared/store/setting.ts b/src/shared/store/setting.ts index fa8cb5c8..e580659a 100644 --- a/src/shared/store/setting.ts +++ b/src/shared/store/setting.ts @@ -93,6 +93,8 @@ const useSettingStore = create()( swarmInfo: null, setSwarmInfo: (swarmInfo: SwarmInfo | null) => set(() => ({ swarmInfo }), false, "setSwarmInfo"), + apiKey: null, + setApiKey: (apiKey: string) => set(() => ({ apiKey }), false, "setApiKey"), environmentDeletion: EnvironmentDeletion.Completed, setEnvironmentDeletion: (environmentDeletion: EnvironmentDeletion) => set(() => ({ environmentDeletion }), false, "setEnvironmentDeletion"), diff --git a/src/shared/types/index.ts b/src/shared/types/index.ts index 5355f14b..f7a90dea 100644 --- a/src/shared/types/index.ts +++ b/src/shared/types/index.ts @@ -126,6 +126,8 @@ export type SettingStore = { environmentDeletion: EnvironmentDeletion | null; setEnvironmentDeletion: (environmentDeletion: EnvironmentDeletion) => void; resetSwarm: () => void; + apiKey: string | null; + setApiKey: (apiKey: string) => void; }; export type HeaderProps = {