forked from baron/baron-sso
chore: snapshot local state before dev merge
This commit is contained in:
@@ -28,16 +28,33 @@ describe("admin routes", () => {
|
||||
expect(matches?.at(-1)?.route.path).toBe("system/data-integrity");
|
||||
});
|
||||
|
||||
it("routes global custom claim settings before user detail id matching", () => {
|
||||
it("routes global custom claim settings before user detail id matching", async () => {
|
||||
const matches = matchRoutes(adminRoutes, "/users/custom-claims");
|
||||
const leafRoute = matches?.at(-1)?.route;
|
||||
|
||||
expect(leafRoute?.path).toBe("users/custom-claims");
|
||||
expect(getRouteElementName(leafRoute?.element)).toBe(
|
||||
expect(await getRouteComponentName(leafRoute)).toBe(
|
||||
"GlobalCustomClaimsPage",
|
||||
);
|
||||
});
|
||||
|
||||
it("code-splits tenant detail profile routes away from the initial admin shell", () => {
|
||||
const matches = matchRoutes(
|
||||
adminRoutes,
|
||||
"/tenants/56cd0fd7-b62a-43c0-8db9-74a30468d7cb",
|
||||
);
|
||||
const detailRoute = matches?.find(
|
||||
(match) => match.route.path === "tenants/:tenantId",
|
||||
)?.route;
|
||||
const profileRoute = matches?.at(-1)?.route;
|
||||
|
||||
expect(detailRoute?.element).toBeUndefined();
|
||||
expect(typeof detailRoute?.lazy).toBe("function");
|
||||
expect(profileRoute?.index).toBe(true);
|
||||
expect(profileRoute?.element).toBeUndefined();
|
||||
expect(typeof profileRoute?.lazy).toBe("function");
|
||||
});
|
||||
|
||||
it("keeps protected admin pages behind an auth guard before mounting the layout", () => {
|
||||
const rootRoute = adminRoutes.find((route) => route.path === "/");
|
||||
const protectedShellRoute = rootRoute?.children?.[0];
|
||||
@@ -48,6 +65,29 @@ describe("admin routes", () => {
|
||||
});
|
||||
});
|
||||
|
||||
async function getRouteComponentName(route: unknown) {
|
||||
if (
|
||||
typeof route === "object" &&
|
||||
route !== null &&
|
||||
"lazy" in route &&
|
||||
typeof route.lazy === "function"
|
||||
) {
|
||||
const lazyRoute = await route.lazy();
|
||||
if ("Component" in lazyRoute && typeof lazyRoute.Component === "function") {
|
||||
return lazyRoute.Component.name;
|
||||
}
|
||||
if ("element" in lazyRoute) {
|
||||
return getRouteElementName(lazyRoute.element);
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof route === "object" && route !== null && "element" in route) {
|
||||
return getRouteElementName(route.element);
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function getRouteElementName(element: unknown) {
|
||||
if (
|
||||
typeof element === "object" &&
|
||||
|
||||
@@ -1,32 +1,33 @@
|
||||
import type { ComponentType } from "react";
|
||||
import type { RouteObject } from "react-router-dom";
|
||||
import { createBrowserRouter } from "react-router-dom";
|
||||
import AppLayout from "../components/layout/AppLayout";
|
||||
import ApiKeyCreatePage from "../features/api-keys/ApiKeyCreatePage";
|
||||
import ApiKeyListPage from "../features/api-keys/ApiKeyListPage";
|
||||
import AuditLogsPage from "../features/audit/AuditLogsPage";
|
||||
import AuthCallbackPage from "../features/auth/AuthCallbackPage";
|
||||
import AuthGuard from "../features/auth/AuthGuard";
|
||||
import AuthPage from "../features/auth/AuthPage";
|
||||
import LoginPage from "../features/auth/LoginPage";
|
||||
import DataIntegrityPage from "../features/integrity/DataIntegrityPage";
|
||||
import OrySSOTPage from "../features/ory-ssot/OrySSOTPage";
|
||||
import GlobalOverviewPage from "../features/overview/GlobalOverviewPage";
|
||||
import { TenantAdminsAndOwnersTab } from "../features/tenants/routes/TenantAdminsAndOwnersTab";
|
||||
import TenantCreatePage from "../features/tenants/routes/TenantCreatePage";
|
||||
import TenantDetailPage from "../features/tenants/routes/TenantDetailPage";
|
||||
import { TenantFineGrainedPermissionsPage } from "../features/tenants/routes/TenantFineGrainedPermissionsPage";
|
||||
import { TenantFineGrainedPermissionsTab } from "../features/tenants/routes/TenantFineGrainedPermissionsTab";
|
||||
import TenantListPage from "../features/tenants/routes/TenantListPage";
|
||||
import { TenantProfilePage } from "../features/tenants/routes/TenantProfilePage";
|
||||
import { TenantSchemaPage } from "../features/tenants/routes/TenantSchemaPage";
|
||||
import { TenantWorksmobilePage } from "../features/tenants/routes/TenantWorksmobilePage";
|
||||
import TenantUserGroupsTab from "../features/user-groups/routes/TenantUserGroupsTab";
|
||||
import GlobalCustomClaimsPage from "../features/users/GlobalCustomClaimsPage";
|
||||
import UserCreatePage from "../features/users/UserCreatePage";
|
||||
import UserDetailPage from "../features/users/UserDetailPage";
|
||||
import UserListPage from "../features/users/UserListPage";
|
||||
import { ADMIN_AUTH_CALLBACK_PATH } from "../lib/authConfig";
|
||||
|
||||
type RouteModule = {
|
||||
default: ComponentType;
|
||||
};
|
||||
|
||||
function lazyDefault(loader: () => Promise<RouteModule>) {
|
||||
return async () => {
|
||||
const module = await loader();
|
||||
return { Component: module.default };
|
||||
};
|
||||
}
|
||||
|
||||
function lazyNamed<TModule, TKey extends keyof TModule>(
|
||||
loader: () => Promise<TModule>,
|
||||
key: TKey,
|
||||
) {
|
||||
return async () => {
|
||||
const module = await loader();
|
||||
return { Component: module[key] as ComponentType };
|
||||
};
|
||||
}
|
||||
|
||||
export const adminRoutes: RouteObject[] = [
|
||||
{
|
||||
path: "/login",
|
||||
@@ -43,42 +44,147 @@ export const adminRoutes: RouteObject[] = [
|
||||
{
|
||||
element: <AppLayout />,
|
||||
children: [
|
||||
{ index: true, element: <GlobalOverviewPage /> },
|
||||
{ path: "audit-logs", element: <AuditLogsPage /> },
|
||||
{ path: "auth", element: <AuthPage /> },
|
||||
{ path: "users", element: <UserListPage /> },
|
||||
{ path: "users/custom-claims", element: <GlobalCustomClaimsPage /> },
|
||||
{ path: "users/new", element: <UserCreatePage /> },
|
||||
{ path: "users/:id", element: <UserDetailPage /> },
|
||||
{ path: "tenants", element: <TenantListPage /> },
|
||||
{ path: "tenants/new", element: <TenantCreatePage /> },
|
||||
{ path: "worksmobile", element: <TenantWorksmobilePage /> },
|
||||
{
|
||||
index: true,
|
||||
lazy: lazyDefault(
|
||||
() => import("../features/overview/GlobalOverviewPage"),
|
||||
),
|
||||
},
|
||||
{
|
||||
path: "audit-logs",
|
||||
lazy: lazyDefault(() => import("../features/audit/AuditLogsPage")),
|
||||
},
|
||||
{
|
||||
path: "auth",
|
||||
lazy: lazyDefault(() => import("../features/auth/AuthPage")),
|
||||
},
|
||||
{
|
||||
path: "users",
|
||||
lazy: lazyDefault(() => import("../features/users/UserListPage")),
|
||||
},
|
||||
{
|
||||
path: "users/custom-claims",
|
||||
lazy: lazyDefault(
|
||||
() => import("../features/users/GlobalCustomClaimsPage"),
|
||||
),
|
||||
},
|
||||
{
|
||||
path: "users/new",
|
||||
lazy: lazyDefault(() => import("../features/users/UserCreatePage")),
|
||||
},
|
||||
{
|
||||
path: "users/:id",
|
||||
lazy: lazyDefault(() => import("../features/users/UserDetailPage")),
|
||||
},
|
||||
{
|
||||
path: "tenants",
|
||||
lazy: lazyDefault(
|
||||
() => import("../features/tenants/routes/TenantListPage"),
|
||||
),
|
||||
},
|
||||
{
|
||||
path: "tenants/new",
|
||||
lazy: lazyDefault(
|
||||
() => import("../features/tenants/routes/TenantCreatePage"),
|
||||
),
|
||||
},
|
||||
{
|
||||
path: "worksmobile",
|
||||
lazy: lazyNamed(
|
||||
() => import("../features/tenants/routes/TenantWorksmobilePage"),
|
||||
"TenantWorksmobilePage",
|
||||
),
|
||||
},
|
||||
{
|
||||
path: "permissions-direct",
|
||||
element: <TenantFineGrainedPermissionsPage />,
|
||||
lazy: lazyNamed(
|
||||
() =>
|
||||
import(
|
||||
"../features/tenants/routes/TenantFineGrainedPermissionsPage"
|
||||
),
|
||||
"TenantFineGrainedPermissionsPage",
|
||||
),
|
||||
},
|
||||
{
|
||||
path: "tenants/:tenantId",
|
||||
element: <TenantDetailPage />,
|
||||
lazy: lazyDefault(
|
||||
() => import("../features/tenants/routes/TenantDetailPage"),
|
||||
),
|
||||
children: [
|
||||
{ index: true, element: <TenantProfilePage /> },
|
||||
{ path: "permissions", element: <TenantAdminsAndOwnersTab /> },
|
||||
{ path: "organization", element: <TenantUserGroupsTab /> },
|
||||
{ path: "schema", element: <TenantSchemaPage /> },
|
||||
{
|
||||
index: true,
|
||||
lazy: lazyNamed(
|
||||
() => import("../features/tenants/routes/TenantProfilePage"),
|
||||
"TenantProfilePage",
|
||||
),
|
||||
},
|
||||
{
|
||||
path: "permissions",
|
||||
lazy: lazyNamed(
|
||||
() =>
|
||||
import(
|
||||
"../features/tenants/routes/TenantAdminsAndOwnersTab"
|
||||
),
|
||||
"TenantAdminsAndOwnersTab",
|
||||
),
|
||||
},
|
||||
{
|
||||
path: "organization",
|
||||
lazy: lazyDefault(
|
||||
() =>
|
||||
import(
|
||||
"../features/user-groups/routes/TenantUserGroupsTab"
|
||||
),
|
||||
),
|
||||
},
|
||||
{
|
||||
path: "schema",
|
||||
lazy: lazyNamed(
|
||||
() => import("../features/tenants/routes/TenantSchemaPage"),
|
||||
"TenantSchemaPage",
|
||||
),
|
||||
},
|
||||
{
|
||||
path: "relations",
|
||||
element: <TenantFineGrainedPermissionsTab />,
|
||||
lazy: lazyNamed(
|
||||
() =>
|
||||
import(
|
||||
"../features/tenants/routes/TenantFineGrainedPermissionsTab"
|
||||
),
|
||||
"TenantFineGrainedPermissionsTab",
|
||||
),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: "tenants/:tenantId/organization/:id",
|
||||
element: <TenantUserGroupsTab />,
|
||||
lazy: lazyDefault(
|
||||
() =>
|
||||
import("../features/user-groups/routes/TenantUserGroupsTab"),
|
||||
),
|
||||
},
|
||||
{
|
||||
path: "api-keys",
|
||||
lazy: lazyDefault(
|
||||
() => import("../features/api-keys/ApiKeyListPage"),
|
||||
),
|
||||
},
|
||||
{
|
||||
path: "api-keys/new",
|
||||
lazy: lazyDefault(
|
||||
() => import("../features/api-keys/ApiKeyCreatePage"),
|
||||
),
|
||||
},
|
||||
{
|
||||
path: "system/ory-ssot",
|
||||
lazy: lazyDefault(() => import("../features/ory-ssot/OrySSOTPage")),
|
||||
},
|
||||
{
|
||||
path: "system/data-integrity",
|
||||
lazy: lazyDefault(
|
||||
() => import("../features/integrity/DataIntegrityPage"),
|
||||
),
|
||||
},
|
||||
{ path: "api-keys", element: <ApiKeyListPage /> },
|
||||
{ path: "api-keys/new", element: <ApiKeyCreatePage /> },
|
||||
{ path: "system/ory-ssot", element: <OrySSOTPage /> },
|
||||
{ path: "system/data-integrity", element: <DataIntegrityPage /> },
|
||||
],
|
||||
},
|
||||
],
|
||||
|
||||
Reference in New Issue
Block a user