feat: role system
This commit is contained in:
@@ -37,7 +37,7 @@ import {
|
||||
ArticlePreviewPage,
|
||||
CountryAddPage,
|
||||
} from "@pages";
|
||||
import { authStore, createSightStore, editSightStore } from "@shared";
|
||||
import { authStore, createSightStore, editSightStore, ROUTE_REQUIRED_RESOURCES } from "@shared";
|
||||
import { Layout } from "@widgets";
|
||||
import { runInAction } from "mobx";
|
||||
import React, { useEffect } from "react";
|
||||
@@ -48,6 +48,7 @@ import {
|
||||
Navigate,
|
||||
Outlet,
|
||||
useLocation,
|
||||
useMatches,
|
||||
} from "react-router-dom";
|
||||
|
||||
const PublicRoute = ({ children }: { children: React.ReactNode }) => {
|
||||
@@ -65,15 +66,28 @@ const ProtectedRoute = ({ children }: { children: React.ReactNode }) => {
|
||||
const need_auth = import.meta.env.VITE_NEED_AUTH == "true";
|
||||
|
||||
const location = useLocation();
|
||||
const matches = useMatches();
|
||||
|
||||
if (!isAuthenticated && need_auth) {
|
||||
return <Navigate to="/login" replace />;
|
||||
}
|
||||
|
||||
if (location.pathname === "/") {
|
||||
if (location.pathname === "/" && authStore.canRead("map")) {
|
||||
return <Navigate to="/map" replace />;
|
||||
}
|
||||
|
||||
const lastMatch = matches[matches.length - 1] as
|
||||
| { handle?: { permissions?: string[] } }
|
||||
| undefined;
|
||||
const requiredPermissions = lastMatch?.handle?.permissions ?? [];
|
||||
|
||||
if (
|
||||
requiredPermissions.length > 0 &&
|
||||
!requiredPermissions.every((permission) => authStore.canAccess(permission))
|
||||
) {
|
||||
return <Navigate to="/" replace />;
|
||||
}
|
||||
|
||||
return <>{children}</>;
|
||||
};
|
||||
|
||||
@@ -102,7 +116,10 @@ const router = createBrowserRouter([
|
||||
</PublicRoute>
|
||||
),
|
||||
},
|
||||
{ path: "route-preview/:id", element: <RoutePreview /> },
|
||||
{
|
||||
path: "route-preview/:id",
|
||||
element: <RoutePreview />,
|
||||
},
|
||||
{
|
||||
path: "/",
|
||||
element: (
|
||||
@@ -115,48 +132,258 @@ const router = createBrowserRouter([
|
||||
</ProtectedRoute>
|
||||
),
|
||||
children: [
|
||||
{ index: true, element: <MainPage /> },
|
||||
{
|
||||
index: true,
|
||||
element: <MainPage />,
|
||||
handle: {
|
||||
permissions: ROUTE_REQUIRED_RESOURCES["/"],
|
||||
},
|
||||
},
|
||||
|
||||
{ path: "sight", element: <SightListPage /> },
|
||||
{ path: "sight/create", element: <CreateSightPage /> },
|
||||
{ path: "sight/:id/edit", element: <EditSightPage /> },
|
||||
{
|
||||
path: "sight",
|
||||
element: <SightListPage />,
|
||||
handle: {
|
||||
permissions: ROUTE_REQUIRED_RESOURCES["/sight"],
|
||||
},
|
||||
},
|
||||
{
|
||||
path: "sight/create",
|
||||
element: <CreateSightPage />,
|
||||
handle: {
|
||||
permissions: ROUTE_REQUIRED_RESOURCES["/sight/create"],
|
||||
},
|
||||
},
|
||||
{
|
||||
path: "sight/:id/edit",
|
||||
element: <EditSightPage />,
|
||||
handle: {
|
||||
permissions: ROUTE_REQUIRED_RESOURCES["/sight/:id/edit"],
|
||||
},
|
||||
},
|
||||
|
||||
{ path: "devices", element: <DevicesPage /> },
|
||||
{
|
||||
path: "devices",
|
||||
element: <DevicesPage />,
|
||||
handle: {
|
||||
permissions: ROUTE_REQUIRED_RESOURCES["/devices"],
|
||||
},
|
||||
},
|
||||
|
||||
{ path: "map", element: <MapPage /> },
|
||||
{
|
||||
path: "map",
|
||||
element: <MapPage />,
|
||||
handle: {
|
||||
permissions: ROUTE_REQUIRED_RESOURCES["/map"],
|
||||
},
|
||||
},
|
||||
|
||||
{ path: "media", element: <MediaListPage /> },
|
||||
{ path: "media/:id", element: <MediaPreviewPage /> },
|
||||
{ path: "media/:id/edit", element: <MediaEditPage /> },
|
||||
{
|
||||
path: "media",
|
||||
element: <MediaListPage />,
|
||||
handle: {
|
||||
permissions: ROUTE_REQUIRED_RESOURCES["/media"],
|
||||
},
|
||||
},
|
||||
{
|
||||
path: "media/:id",
|
||||
element: <MediaPreviewPage />,
|
||||
handle: {
|
||||
permissions: ROUTE_REQUIRED_RESOURCES["/media/:id"],
|
||||
},
|
||||
},
|
||||
{
|
||||
path: "media/:id/edit",
|
||||
element: <MediaEditPage />,
|
||||
handle: {
|
||||
permissions: ROUTE_REQUIRED_RESOURCES["/media/:id/edit"],
|
||||
},
|
||||
},
|
||||
|
||||
{ path: "country", element: <CountryListPage /> },
|
||||
{ path: "country/create", element: <CountryCreatePage /> },
|
||||
{ path: "country/add", element: <CountryAddPage /> },
|
||||
{ path: "country/:id/edit", element: <CountryEditPage /> },
|
||||
{ path: "city", element: <CityListPage /> },
|
||||
{ path: "city/create", element: <CityCreatePage /> },
|
||||
{ path: "city/:id/edit", element: <CityEditPage /> },
|
||||
{ path: "route", element: <RouteListPage /> },
|
||||
{ path: "route/create", element: <RouteCreatePage /> },
|
||||
{ path: "route/:id/edit", element: <RouteEditPage /> },
|
||||
{
|
||||
path: "country",
|
||||
element: <CountryListPage />,
|
||||
handle: {
|
||||
permissions: ROUTE_REQUIRED_RESOURCES["/country"],
|
||||
},
|
||||
},
|
||||
{
|
||||
path: "country/create",
|
||||
element: <CountryCreatePage />,
|
||||
handle: {
|
||||
permissions: ROUTE_REQUIRED_RESOURCES["/country/create"],
|
||||
},
|
||||
},
|
||||
{
|
||||
path: "country/add",
|
||||
element: <CountryAddPage />,
|
||||
handle: {
|
||||
permissions: ROUTE_REQUIRED_RESOURCES["/country/add"],
|
||||
},
|
||||
},
|
||||
{
|
||||
path: "country/:id/edit",
|
||||
element: <CountryEditPage />,
|
||||
handle: {
|
||||
permissions: ROUTE_REQUIRED_RESOURCES["/country/:id/edit"],
|
||||
},
|
||||
},
|
||||
{
|
||||
path: "city",
|
||||
element: <CityListPage />,
|
||||
handle: {
|
||||
permissions: ROUTE_REQUIRED_RESOURCES["/city"],
|
||||
},
|
||||
},
|
||||
{
|
||||
path: "city/create",
|
||||
element: <CityCreatePage />,
|
||||
handle: {
|
||||
permissions: ROUTE_REQUIRED_RESOURCES["/city/create"],
|
||||
},
|
||||
},
|
||||
{
|
||||
path: "city/:id/edit",
|
||||
element: <CityEditPage />,
|
||||
handle: {
|
||||
permissions: ROUTE_REQUIRED_RESOURCES["/city/:id/edit"],
|
||||
},
|
||||
},
|
||||
{
|
||||
path: "route",
|
||||
element: <RouteListPage />,
|
||||
handle: {
|
||||
permissions: ROUTE_REQUIRED_RESOURCES["/route"],
|
||||
},
|
||||
},
|
||||
{
|
||||
path: "route/create",
|
||||
element: <RouteCreatePage />,
|
||||
handle: {
|
||||
permissions: ROUTE_REQUIRED_RESOURCES["/route/create"],
|
||||
},
|
||||
},
|
||||
{
|
||||
path: "route/:id/edit",
|
||||
element: <RouteEditPage />,
|
||||
handle: {
|
||||
permissions: ROUTE_REQUIRED_RESOURCES["/route/:id/edit"],
|
||||
},
|
||||
},
|
||||
|
||||
{ path: "user", element: <UserListPage /> },
|
||||
{ path: "user/create", element: <UserCreatePage /> },
|
||||
{ path: "user/:id/edit", element: <UserEditPage /> },
|
||||
{ path: "snapshot", element: <SnapshotListPage /> },
|
||||
{ path: "snapshot/create", element: <SnapshotCreatePage /> },
|
||||
{
|
||||
path: "user",
|
||||
element: <UserListPage />,
|
||||
handle: {
|
||||
permissions: ROUTE_REQUIRED_RESOURCES["/user"],
|
||||
},
|
||||
},
|
||||
{
|
||||
path: "user/create",
|
||||
element: <UserCreatePage />,
|
||||
handle: {
|
||||
permissions: ROUTE_REQUIRED_RESOURCES["/user/create"],
|
||||
},
|
||||
},
|
||||
{
|
||||
path: "user/:id/edit",
|
||||
element: <UserEditPage />,
|
||||
handle: {
|
||||
permissions: ROUTE_REQUIRED_RESOURCES["/user/:id/edit"],
|
||||
},
|
||||
},
|
||||
{
|
||||
path: "snapshot",
|
||||
element: <SnapshotListPage />,
|
||||
handle: {
|
||||
permissions: ROUTE_REQUIRED_RESOURCES["/snapshot"],
|
||||
},
|
||||
},
|
||||
{
|
||||
path: "snapshot/create",
|
||||
element: <SnapshotCreatePage />,
|
||||
handle: {
|
||||
permissions: ROUTE_REQUIRED_RESOURCES["/snapshot/create"],
|
||||
},
|
||||
},
|
||||
|
||||
{ path: "carrier", element: <CarrierListPage /> },
|
||||
{ path: "carrier/create", element: <CarrierCreatePage /> },
|
||||
{ path: "carrier/:id/edit", element: <CarrierEditPage /> },
|
||||
{ path: "station", element: <StationListPage /> },
|
||||
{ path: "station/create", element: <StationCreatePage /> },
|
||||
{ path: "station/:id", element: <StationPreviewPage /> },
|
||||
{ path: "station/:id/edit", element: <StationEditPage /> },
|
||||
{ path: "vehicle/create", element: <VehicleCreatePage /> },
|
||||
{ path: "vehicle/:id/edit", element: <VehicleEditPage /> },
|
||||
{ path: "article", element: <ArticleListPage /> },
|
||||
{ path: "article/:id", element: <ArticlePreviewPage /> },
|
||||
{
|
||||
path: "carrier",
|
||||
element: <CarrierListPage />,
|
||||
handle: {
|
||||
permissions: ROUTE_REQUIRED_RESOURCES["/carrier"],
|
||||
},
|
||||
},
|
||||
{
|
||||
path: "carrier/create",
|
||||
element: <CarrierCreatePage />,
|
||||
handle: {
|
||||
permissions: ROUTE_REQUIRED_RESOURCES["/carrier/create"],
|
||||
},
|
||||
},
|
||||
{
|
||||
path: "carrier/:id/edit",
|
||||
element: <CarrierEditPage />,
|
||||
handle: {
|
||||
permissions: ROUTE_REQUIRED_RESOURCES["/carrier/:id/edit"],
|
||||
},
|
||||
},
|
||||
{
|
||||
path: "station",
|
||||
element: <StationListPage />,
|
||||
handle: {
|
||||
permissions: ROUTE_REQUIRED_RESOURCES["/station"],
|
||||
},
|
||||
},
|
||||
{
|
||||
path: "station/create",
|
||||
element: <StationCreatePage />,
|
||||
handle: {
|
||||
permissions: ROUTE_REQUIRED_RESOURCES["/station/create"],
|
||||
},
|
||||
},
|
||||
{
|
||||
path: "station/:id",
|
||||
element: <StationPreviewPage />,
|
||||
handle: {
|
||||
permissions: ROUTE_REQUIRED_RESOURCES["/station/:id"],
|
||||
},
|
||||
},
|
||||
{
|
||||
path: "station/:id/edit",
|
||||
element: <StationEditPage />,
|
||||
handle: {
|
||||
permissions: ROUTE_REQUIRED_RESOURCES["/station/:id/edit"],
|
||||
},
|
||||
},
|
||||
{
|
||||
path: "vehicle/create",
|
||||
element: <VehicleCreatePage />,
|
||||
handle: {
|
||||
permissions: ROUTE_REQUIRED_RESOURCES["/vehicle/create"],
|
||||
},
|
||||
},
|
||||
{
|
||||
path: "vehicle/:id/edit",
|
||||
element: <VehicleEditPage />,
|
||||
handle: {
|
||||
permissions: ROUTE_REQUIRED_RESOURCES["/vehicle/:id/edit"],
|
||||
},
|
||||
},
|
||||
{
|
||||
path: "article",
|
||||
element: <ArticleListPage />,
|
||||
handle: {
|
||||
permissions: ROUTE_REQUIRED_RESOURCES["/article"],
|
||||
},
|
||||
},
|
||||
{
|
||||
path: "article/:id",
|
||||
element: <ArticlePreviewPage />,
|
||||
handle: {
|
||||
permissions: ROUTE_REQUIRED_RESOURCES["/article/:id"],
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
]);
|
||||
|
||||
Reference in New Issue
Block a user