diff --git a/src/pages/UnauthorizedPage.tsx b/src/pages/UnauthorizedPage.tsx
index 50fdf52..c3a98b8 100644
--- a/src/pages/UnauthorizedPage.tsx
+++ b/src/pages/UnauthorizedPage.tsx
@@ -1,4 +1,5 @@
-import { Stack, Typography } from "@mui/material";
+import { Box, Stack, Typography } from "@mui/material";
+import { Row } from "../ui/Row";
export function UnauthorizedPage() {
return (
@@ -13,9 +14,17 @@ export function UnauthorizedPage() {
minHeight={500}
height="calc(100vh - 230px)"
>
-
- Vous n'avez pas les droits nécessaires pour accéder à Platine Gestion
-
+
+
+ {"Vous n'êtes pas autorisé à accéder à "}
+
+
+
+ Platine
+
+ Gestion
+
+
>
);
diff --git a/src/routes.tsx b/src/routes.tsx
index deae304..fbe5ecc 100644
--- a/src/routes.tsx
+++ b/src/routes.tsx
@@ -1,7 +1,7 @@
import { SearchPage } from "./pages/SearchPage";
import { Home } from "./pages/Home.tsx";
import { Outlet, redirect, RouteObject } from "react-router-dom";
-import { Layout } from "./ui/Layout";
+import { Layout, LayoutWithAuth } from "./ui/Layout";
import { PageError } from "./ui/PageError";
import { SurveyPage } from "./pages/SurveyPage";
import { ContactPage } from "./pages/ContactPage";
@@ -11,15 +11,25 @@ import { SearchSurveys } from "./pages/Search/SearchSurveys.tsx";
import { SearchSurveyUnits } from "./pages/Search/SearchSurveyUnits.tsx";
import { SurveyUnitPage } from "./pages/SurveyUnitPage.tsx";
import { CreateContactPage } from "./pages/CreateContactPage.tsx";
+import { UnauthorizedPage } from "./pages/UnauthorizedPage.tsx";
+import { LogoutPage } from "./pages/Logout.tsx";
export const routes: RouteObject[] = [
{
- path: "/",
+ path: "logout",
element: (
-
+
),
+ },
+ {
+ path: "/",
+ element: (
+
+
+
+ ),
errorElement:
,
children: [
{
@@ -41,3 +51,39 @@ export const routes: RouteObject[] = [
],
},
];
+
+export const unauthorizedRoutes: RouteObject[] = [
+ {
+ path: "/logout",
+ element: (
+
+
+
+ ),
+ },
+ {
+ path: "/*",
+ element: (
+
+
+
+ ),
+ errorElement:
,
+ },
+];
+
+/* export const unauthenticatedRoutes: RouteObject[] = [
+ {
+ path: "/",
+ element: (
+
+
+
+ ),
+ errorElement:
,
+ children: [
+ { path: "logout", element:
},
+ { path: "", element:
},
+ ],
+ },
+]; */
diff --git a/src/ui/Header.tsx b/src/ui/Header.tsx
index ace24c5..fed957b 100644
--- a/src/ui/Header.tsx
+++ b/src/ui/Header.tsx
@@ -4,12 +4,14 @@ import ExitToAppIcon from "@mui/icons-material/ExitToApp";
import { Link as RouterLink } from "react-router-dom";
import { Row } from "./Row.tsx";
import { PropsWithChildren } from "react";
-import { useUser, useLogout } from "../hooks/useAuth.ts";
+import { useMaybeUser, useLogout } from "../hooks/useAuth.ts";
import packageInfo from "../../package.json";
+import { useHasPermission } from "../hooks/usePermissions.ts";
export function Header() {
- const { preferred_username } = useUser();
+ const user = useMaybeUser();
const logout = useLogout();
+ const activeSettings = useHasPermission("ACCESS_SETTINGS");
return (
@@ -28,20 +30,24 @@ export function Header() {
- {preferred_username}
-
-
-
-
- logout({
- redirectTo: "specific url",
- url: "",
- })
- }
- >
-
-
+ {user?.preferred_username}
+ {activeSettings && (
+
+
+
+ )}
+ {logout && (
+
+ logout({
+ redirectTo: "specific url",
+ url: `${import.meta.env.VITE_APP_URL}/logout`,
+ })
+ }
+ >
+
+
+ )}
);
diff --git a/src/ui/Layout.tsx b/src/ui/Layout.tsx
index 99256bd..7ebe8b4 100644
--- a/src/ui/Layout.tsx
+++ b/src/ui/Layout.tsx
@@ -1,5 +1,8 @@
import { type PropsWithChildren } from "react";
import { Header } from "./Header";
+import { useIsAuthenticated } from "../hooks/useAuth";
+import { CircularProgress } from "@mui/material";
+import { Row } from "../ui/Row";
export function Layout({ children }: PropsWithChildren) {
return (
@@ -9,3 +12,22 @@ export function Layout({ children }: PropsWithChildren) {
>
);
}
+
+export function LayoutWithAuth({ children }: PropsWithChildren) {
+ const { isAuthenticated } = useIsAuthenticated();
+
+ if (!isAuthenticated) {
+ return (
+
+
+
+ );
+ }
+
+ return (
+ <>
+
+ {children}
+ >
+ );
+}
diff --git a/src/vite-env.d.ts b/src/vite-env.d.ts
index 4c741ad..ee62647 100644
--- a/src/vite-env.d.ts
+++ b/src/vite-env.d.ts
@@ -1,14 +1,40 @@
-///
-interface ImportMetaEnv {
- readonly VITE_API_ENDPOINT: string;
- readonly VITE_AUTH_TYPE: string;
- readonly VITE_OIDC_CLIENT_ID: string;
- readonly VITE_OIDC_ISSUER: string;
- readonly VITE_IDENTITY_PROVIDER: string;
+///
+type ImportMetaEnv = {
+ // Auto-generated by `npx vite-envs update-types` and hot-reloaded by the `vite-env` plugin
+ VITE_API_ENDPOINT: string
+ VITE_AUTH_TYPE: string
+ VITE_OIDC_CLIENT_ID: string
+ VITE_OIDC_ISSUER: string
+ VITE_IDENTITY_PROVIDER: string
+ VITE_ADMIN_LDAP_ROLE: string
+ VITE_USER_LDAP_ROLE: string
+ VITE_APP_URL: string
+ BASE_URL: string
+ MODE: string
+ DEV: boolean
+ PROD: boolean
+ // @user-defined-start
+ /*
+ * Here you can define your own special variables
+ * that would be available on `import.meta.env` but
+ * that vite-envs does not know about.
+ * This section will be preserved thanks to the special comments.
+ * Example:
+ */
+ SSR: boolean;
+ // @user-defined-end
}
interface ImportMeta {
- readonly env: ImportMetaEnv;
+ // Auto-generated by `npx vite-envs update-types`
+
+ url: string
+
+ readonly hot?: import('vite-envs/types/hot').ViteHotContext
+
+ readonly env: ImportMetaEnv
+
+ glob: import('vite-envs/types/importGlob').ImportGlobFunction
}
type ObjectKeys
= T extends object
diff --git a/yarn.lock b/yarn.lock
index de52dbd..1a2a210 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -227,6 +227,13 @@
dependencies:
regenerator-runtime "^0.14.0"
+"@babel/runtime@^7.23.8", "@babel/runtime@^7.24.4":
+ version "7.24.4"
+ resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.24.4.tgz#de795accd698007a66ba44add6cc86542aff1edd"
+ integrity sha512-dkxf7+hn8mFBwKjs9bvBlArzLVxVbS8usaPUDd5p2a9JCL9tB8OaOVN1isD4+Xyk4ns89/xeOmbQvgdK7IIVdA==
+ dependencies:
+ regenerator-runtime "^0.14.0"
+
"@babel/template@^7.22.15":
version "7.22.15"
resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.22.15.tgz#09576efc3830f0430f4548ef971dde1350ef2f38"
@@ -1626,6 +1633,14 @@ fast-shallow-equal@^1.0.0:
resolved "https://registry.yarnpkg.com/fast-shallow-equal/-/fast-shallow-equal-1.0.0.tgz#d4dcaf6472440dcefa6f88b98e3251e27f25628b"
integrity sha512-HPtaa38cPgWvaCFmRNhlc6NG7pv6NUHqjPgVAkWGoB9mQMwYB27/K0CvOM5Czy+qpT3e8XJ6Q4aPAnzpNpzNaw==
+fast-unique-numbers@^8.0.13:
+ version "8.0.13"
+ resolved "https://registry.yarnpkg.com/fast-unique-numbers/-/fast-unique-numbers-8.0.13.tgz#3c87232061ff5f408a216e1f0121232f76f695d7"
+ integrity sha512-7OnTFAVPefgw2eBJ1xj2PGGR9FwYzSUso9decayHgCDX4sJkHLdcsYTytTg+tYv+wKF3U8gJuSBz2jJpQV4u/g==
+ dependencies:
+ "@babel/runtime" "^7.23.8"
+ tslib "^2.6.2"
+
fastest-stable-stringify@^2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/fastest-stable-stringify/-/fastest-stable-stringify-2.0.2.tgz#3757a6774f6ec8de40c4e86ec28ea02417214c76"
@@ -2376,7 +2391,7 @@ object-assign@^4.1.1:
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==
-oidc-client-ts@^2.3.0:
+oidc-client-ts@2.4.0:
version "2.4.0"
resolved "https://registry.yarnpkg.com/oidc-client-ts/-/oidc-client-ts-2.4.0.tgz#764c8a33de542026e2798de9849ce8049047d7e5"
integrity sha512-WijhkTrlXK2VvgGoakWJiBdfIsVGz6CFzgjNNqZU1hPKV2kyeEaJgLs7RwuiSp2WhLfWBQuLvr2SxVlZnk3N1w==
@@ -2384,14 +2399,15 @@ oidc-client-ts@^2.3.0:
crypto-js "^4.2.0"
jwt-decode "^3.1.2"
-oidc-spa@^4.0.0:
- version "4.0.0"
- resolved "https://registry.yarnpkg.com/oidc-spa/-/oidc-spa-4.0.0.tgz#7cec1683686cd6f2b9c85547107b19b6b54ffd39"
- integrity sha512-Zy386BfS/LbkUopNTA1xFCWYIMc7fFrQ1Iyc58vt+2dAezTAt15F6YTrYGXGCa4P0q8SpO6Avu8/OmHyO67d9w==
+oidc-spa@^4.6.0:
+ version "4.6.0"
+ resolved "https://registry.yarnpkg.com/oidc-spa/-/oidc-spa-4.6.0.tgz#3482e14c405b0ef9c7673ae7be4c1928d0b06a65"
+ integrity sha512-a1y+PSBtlhzyKJ7ucGx9Rp+aJhV2cL36rmO/imIHkfb4ig/5xOQtzl9Ee9hRbAIrwVAu/lpR9PfUXTq2bLrG2Q==
dependencies:
jwt-decode "^3.1.2"
- oidc-client-ts "^2.3.0"
+ oidc-client-ts "2.4.0"
tsafe "^1.6.5"
+ worker-timers "^7.1.7"
once@^1.3.0:
version "1.4.0"
@@ -2926,7 +2942,7 @@ tsafe@^1.6.5, tsafe@^1.6.6:
resolved "https://registry.yarnpkg.com/tsafe/-/tsafe-1.6.6.tgz#fd93e64d6eb13ef83ed1650669cc24bad4f5df9f"
integrity sha512-gzkapsdbMNwBnTIjgO758GujLCj031IgHK/PKr2mrmkCSJMhSOR5FeOuSxKLMUoYc0vAA4RGEYYbjt/v6afD3g==
-tslib@^2.1.0:
+tslib@^2.1.0, tslib@^2.6.2:
version "2.6.2"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae"
integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==
@@ -3065,6 +3081,34 @@ which@^2.0.1:
dependencies:
isexe "^2.0.0"
+worker-timers-broker@^6.1.7:
+ version "6.1.7"
+ resolved "https://registry.yarnpkg.com/worker-timers-broker/-/worker-timers-broker-6.1.7.tgz#c570552f1576f81226dbeb0dc14bb64144c9597c"
+ integrity sha512-8hb4lSMAijDY/Dp/MOw9Hc2x6uU59XWFYjcWQgC4bai+sxcLXjeexd9aYKdYMFZPiPoieGzMYIs9WGpv2Co3eA==
+ dependencies:
+ "@babel/runtime" "^7.24.4"
+ fast-unique-numbers "^8.0.13"
+ tslib "^2.6.2"
+ worker-timers-worker "^7.0.70"
+
+worker-timers-worker@^7.0.70:
+ version "7.0.70"
+ resolved "https://registry.yarnpkg.com/worker-timers-worker/-/worker-timers-worker-7.0.70.tgz#064758e1ca3bed908950d152e3e3006595dd9600"
+ integrity sha512-lemWEME0RHB78hzGkkQcKfF6L82gqVhV3T9iY14jHBhbLxLq9t1RRCLmPDBZV7sdnUoW6Khkfn6coqPjgEK6cw==
+ dependencies:
+ "@babel/runtime" "^7.24.4"
+ tslib "^2.6.2"
+
+worker-timers@^7.1.7:
+ version "7.1.7"
+ resolved "https://registry.yarnpkg.com/worker-timers/-/worker-timers-7.1.7.tgz#1119f6454cb7c8653097ffb66f592115fb6693ea"
+ integrity sha512-Dr4La61d94SjOA8P57h2LN8W3MXOVe/m1P7jER8cmuIy+JaDMqPttSwo6QRJFSK6YnG9cD6SU7J8m7CVlu8jlw==
+ dependencies:
+ "@babel/runtime" "^7.24.4"
+ tslib "^2.6.2"
+ worker-timers-broker "^6.1.7"
+ worker-timers-worker "^7.0.70"
+
wrappy@1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"