1
0
mirror of https://github.com/Stirling-Tools/Stirling-PDF.git synced 2024-11-23 15:21:25 +01:00

Authenticated Routes and Redirects

This commit is contained in:
Felix Kaspar 2024-10-04 17:50:42 +02:00
parent f3697a18e3
commit 74079512d0
8 changed files with 61 additions and 21 deletions

2
client-tauri/.env Normal file
View File

@ -0,0 +1,2 @@
VITE_USE_AUTH=False
VITE_BACKEND=""

View File

@ -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 Home from "./pages/Home";
import Operators from "./pages/Operators"; import Operators from "./pages/Operators";
import NoMatch from "./pages/NoMatch"; import NoMatch from "./pages/NoMatch";
@ -12,6 +12,7 @@ import LanguageDetector from "i18next-browser-languagedetector";
import i18next from "i18next"; import i18next from "i18next";
import resourcesToBackend from "i18next-resources-to-backend"; import resourcesToBackend from "i18next-resources-to-backend";
import { listOperatorNames } from "@stirling-pdf/shared-operations/src/workflow/operatorAccessor"; 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)))) 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({ .init({
@ -26,37 +27,45 @@ i18next.use(LanguageDetector).use(initReactI18next).use(resourcesToBackend((lang
}); // TODO: use i18next.config.ts instead }); // TODO: use i18next.config.ts instead
export default function App() { export default function App() {
return ( return (
<Suspense fallback="loading"> <Suspense fallback={<Loading/>}>
{/* Routes nest inside one another. Nested route paths build upon {/* Routes nest inside one another. Nested route paths build upon
parent route paths, and nested route elements render inside parent route paths, and nested route elements render inside
parent route elements. See the note about <Outlet> below. */} parent route elements. See the note about <Outlet> below. */}
<Routes> <Routes>
<Route path="/" element={<Layout />}> <Route path="/auth" element={<Layout />}>
<Route index element={<Home />} /> <Route index element={<Navigate to="/auth/login" />}/>
<Route path="login" element={"login test string"}></Route>
{/* Using path="*"" means "match anything", so this route <Route path="logout" element={"logout test string"}></Route>
acts like a catch-all for URLs that we don't have explicit <Route path="register" element={"register test string"}></Route>
routes for. */}
<Route path="*" element={<NoMatch />} /> <Route path="*" element={<NoMatch />} />
</Route> </Route>
<Route path="/operators" element={<Layout />}> <Route element={<AuthenticatedRoute />}>
<Route index element={<NoMatch />} /> <Route path="/" element={<Layout />}>
{listOperatorNames().map((name) => { <Route index element={<Home />} />
return <Route key={name} path={name} element={<Operators/>} />; <Route path="*" element={<NoMatch />} />
})} </Route>
<Route path="*" element={<NoMatch />} />
<Route path="/operators" element={<Layout />}>
<Route index element={<NoMatch />} />
{listOperatorNames().map((name) => {
return <Route key={name} path={name} element={<Operators/>} />;
})}
<Route path="*" element={<NoMatch />} />
</Route>
</Route> </Route>
</Routes> </Routes>
</Suspense> </Suspense>
); );
} }
function Loading() {
return "Loading";
}
function Layout() { function Layout() {
const { t } = useTranslation(); const { t } = useTranslation();
console.log(t("inputs.pdffile.name"));
return ( return (
<div lang-direction={t("language.direction")}> <div lang-direction={t("language.direction")}>
<NavBar/> <NavBar/>

View File

@ -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() ? <Outlet /> : <Navigate to="/auth/login" />;
};
export default AuthenticatedRoute;

View File

@ -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

View File

@ -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

View File

@ -0,0 +1,2 @@
// TODO: Register user and login in the same request.
// TODO: Check if user registration & login is enabled on this server

View File

@ -11,7 +11,7 @@ import { useLocation } from 'react-router-dom'
import InputField from "../components/fields/InputField"; import InputField from "../components/fields/InputField";
function Dynamic() { function Operators() {
const [schema, setSchema] = useState<any>(undefined); // TODO: Type as joi type const [schema, setSchema] = useState<any>(undefined); // TODO: Type as joi type
const location = useLocation(); const location = useLocation();
@ -95,4 +95,4 @@ function Dynamic() {
} }
export default Dynamic; export default Operators;

View File

@ -6,7 +6,6 @@ import dynamicImport from 'vite-plugin-dynamic-import';
import compileTime from "vite-plugin-compile-time"; import compileTime from "vite-plugin-compile-time";
import { fileURLToPath, URL } from 'node:url'; import { fileURLToPath, URL } from 'node:url';
// https://vitejs.dev/config/ // https://vitejs.dev/config/
export default defineConfig(async () => ({ export default defineConfig(async () => ({
plugins: [ plugins: [