From 74079512d0748f92e9204deecb504f20049dcdfe Mon Sep 17 00:00:00 2001 From: Felix Kaspar Date: Fri, 4 Oct 2024 17:50:42 +0200 Subject: [PATCH] Authenticated Routes and Redirects --- client-tauri/.env | 2 + client-tauri/src/App.tsx | 45 +++++++++++-------- .../src/components/AuthenticatedRoute.tsx | 22 +++++++++ client-tauri/src/pages/Auth/Login.tsx | 4 ++ client-tauri/src/pages/Auth/Logout.tsx | 2 + client-tauri/src/pages/Auth/Register.tsx | 2 + client-tauri/src/pages/Operators.tsx | 4 +- client-tauri/vite.config.ts | 1 - 8 files changed, 61 insertions(+), 21 deletions(-) create mode 100644 client-tauri/.env create mode 100644 client-tauri/src/components/AuthenticatedRoute.tsx create mode 100644 client-tauri/src/pages/Auth/Login.tsx create mode 100644 client-tauri/src/pages/Auth/Logout.tsx create mode 100644 client-tauri/src/pages/Auth/Register.tsx diff --git a/client-tauri/.env b/client-tauri/.env new file mode 100644 index 00000000..aaa65fec --- /dev/null +++ b/client-tauri/.env @@ -0,0 +1,2 @@ +VITE_USE_AUTH=False +VITE_BACKEND="" \ No newline at end of file diff --git a/client-tauri/src/App.tsx b/client-tauri/src/App.tsx index 594adb29..5dfb30b7 100644 --- a/client-tauri/src/App.tsx +++ b/client-tauri/src/App.tsx @@ -1,6 +1,6 @@ -import { Suspense } from "react"; +import { Fragment, Suspense } from "react"; -import { Routes, Route, Outlet } from "react-router-dom"; +import { Routes, Route, Outlet, Navigate } from "react-router-dom"; import Home from "./pages/Home"; import Operators from "./pages/Operators"; import NoMatch from "./pages/NoMatch"; @@ -12,6 +12,7 @@ import LanguageDetector from "i18next-browser-languagedetector"; import i18next from "i18next"; import resourcesToBackend from "i18next-resources-to-backend"; import { listOperatorNames } from "@stirling-pdf/shared-operations/src/workflow/operatorAccessor"; +import AuthenticatedRoute from "./components/AuthenticatedRoute"; i18next.use(LanguageDetector).use(initReactI18next).use(resourcesToBackend((language: string, namespace: string) => import(`@stirling-pdf/shared-operations/public/locales/${namespace}/${language}.json`).catch((e) => console.warn("some component tried to render with an unsupported language, falling back to en", e)))) .init({ @@ -26,37 +27,45 @@ i18next.use(LanguageDetector).use(initReactI18next).use(resourcesToBackend((lang }); // TODO: use i18next.config.ts instead export default function App() { - return ( - + }> {/* Routes nest inside one another. Nested route paths build upon parent route paths, and nested route elements render inside parent route elements. See the note about below. */} - }> - } /> - - {/* Using path="*"" means "match anything", so this route - acts like a catch-all for URLs that we don't have explicit - routes for. */} + }> + }/> + + + } /> - - }> - } /> - {listOperatorNames().map((name) => { - return } />; - })} - } /> + + }> + }> + } /> + } /> + + + }> + } /> + {listOperatorNames().map((name) => { + return } />; + })} + } /> + ); } +function Loading() { + return "Loading"; +} + function Layout() { const { t } = useTranslation(); - console.log(t("inputs.pdffile.name")); return (
diff --git a/client-tauri/src/components/AuthenticatedRoute.tsx b/client-tauri/src/components/AuthenticatedRoute.tsx new file mode 100644 index 00000000..6eea0710 --- /dev/null +++ b/client-tauri/src/components/AuthenticatedRoute.tsx @@ -0,0 +1,22 @@ +import { ReactNode } from "react"; +import { Navigate, Outlet } from "react-router-dom"; + +interface AuthenticatedRouteProps { + isAuthenticated: boolean; + children?: ReactNode; // Accepting children +} + + +function isAuthenticated() { + if (import.meta.env.VITE_USE_AUTH == "True") { + // TODO: if user is set in localstorage and is valid (either by time or by checking online) return true + return false; + } + return true; +} + +function AuthenticatedRoute({}: {}): JSX.Element { + return isAuthenticated() ? : ; +}; + +export default AuthenticatedRoute; \ No newline at end of file diff --git a/client-tauri/src/pages/Auth/Login.tsx b/client-tauri/src/pages/Auth/Login.tsx new file mode 100644 index 00000000..743fdbf9 --- /dev/null +++ b/client-tauri/src/pages/Auth/Login.tsx @@ -0,0 +1,4 @@ +// TODO: Store user info in localstorage. Session cookie will be set automatically + +// TODO: Check if user login is enabled on this server + diff --git a/client-tauri/src/pages/Auth/Logout.tsx b/client-tauri/src/pages/Auth/Logout.tsx new file mode 100644 index 00000000..efa831c6 --- /dev/null +++ b/client-tauri/src/pages/Auth/Logout.tsx @@ -0,0 +1,2 @@ +// TODO: Delete user info in localstorage. Send request to logout endport session cookie will be removed automatically. +// TODO: Check if user login is enabled on this server \ No newline at end of file diff --git a/client-tauri/src/pages/Auth/Register.tsx b/client-tauri/src/pages/Auth/Register.tsx new file mode 100644 index 00000000..b8911ea1 --- /dev/null +++ b/client-tauri/src/pages/Auth/Register.tsx @@ -0,0 +1,2 @@ +// TODO: Register user and login in the same request. +// TODO: Check if user registration & login is enabled on this server \ No newline at end of file diff --git a/client-tauri/src/pages/Operators.tsx b/client-tauri/src/pages/Operators.tsx index ef0159c8..c21a28f9 100644 --- a/client-tauri/src/pages/Operators.tsx +++ b/client-tauri/src/pages/Operators.tsx @@ -11,7 +11,7 @@ import { useLocation } from 'react-router-dom' import InputField from "../components/fields/InputField"; -function Dynamic() { +function Operators() { const [schema, setSchema] = useState(undefined); // TODO: Type as joi type const location = useLocation(); @@ -95,4 +95,4 @@ function Dynamic() { } -export default Dynamic; +export default Operators; diff --git a/client-tauri/vite.config.ts b/client-tauri/vite.config.ts index 55d8a70d..b621fc0f 100644 --- a/client-tauri/vite.config.ts +++ b/client-tauri/vite.config.ts @@ -6,7 +6,6 @@ import dynamicImport from 'vite-plugin-dynamic-import'; import compileTime from "vite-plugin-compile-time"; import { fileURLToPath, URL } from 'node:url'; - // https://vitejs.dev/config/ export default defineConfig(async () => ({ plugins: [