- Implement PermissionGuard component for route-level permission enforcement - Add tree-based permission checkbox group in role management popup - Gate SSE connection, unread count fetch, and rule edit actions on user permissions - Add skip401Refresh option and auto token refresh on 401 response - Improve alert table with fixed columns, explicit widths, and text ellipsis - Add i18n entries for permission guide and rule menu descriptions (en/zh) - Add expo-api nginx proxy configuration - Add .claude to .gitignore Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
62 lines
1.6 KiB
TypeScript
62 lines
1.6 KiB
TypeScript
import { commonRoutes, roleRoutes } from '../../config/routes';
|
|
|
|
interface RouteItem {
|
|
path?: string;
|
|
access?: string;
|
|
meta?: { permissions?: string[] };
|
|
routes?: RouteItem[];
|
|
}
|
|
|
|
function flattenPermissions(
|
|
routes: RouteItem[],
|
|
parentPath = '',
|
|
inheritedPermissions?: string[],
|
|
): Map<string, string[]> {
|
|
const map = new Map<string, string[]>();
|
|
for (const route of routes) {
|
|
const fullPath = parentPath + (route.path || '');
|
|
const ownPermissions =
|
|
route.access === 'normalRouteFilter' && route.meta?.permissions?.length
|
|
? route.meta.permissions
|
|
: undefined;
|
|
const effectivePermissions = ownPermissions ?? inheritedPermissions;
|
|
|
|
if (effectivePermissions?.length) {
|
|
map.set(fullPath, effectivePermissions);
|
|
}
|
|
|
|
if (route.routes) {
|
|
const children = flattenPermissions(
|
|
route.routes,
|
|
`${fullPath}/`,
|
|
effectivePermissions,
|
|
);
|
|
for (const [path, perms] of children) {
|
|
map.set(path, perms);
|
|
}
|
|
}
|
|
}
|
|
return map;
|
|
}
|
|
|
|
export const routePermissions = flattenPermissions([
|
|
...commonRoutes,
|
|
...roleRoutes,
|
|
]);
|
|
|
|
/**
|
|
* Look up the required permissions for a pathname.
|
|
* Falls back to parent paths if the exact path isn't found (e.g. /rules/liquidity-trade → /rules).
|
|
*/
|
|
export function getRequiredPermissions(pathname: string): string[] | undefined {
|
|
let path = pathname.replace(/\/$/, '') || '/';
|
|
while (path) {
|
|
const perms = routePermissions.get(path);
|
|
if (perms) return perms;
|
|
const i = path.lastIndexOf('/');
|
|
if (i <= 0) break;
|
|
path = path.slice(0, i);
|
|
}
|
|
return undefined;
|
|
}
|