Files
homarr/packages/spotlight/src/modes/page/pages-search-group.tsx
Meier Lukas 0ee343b99e feat: add more group permissions (#1453)
* feat: add more group permissions

* feat: restrict access with app permissions

* feat: restrict access with search-engine permissions

* feat: restrict access with media permissions

* refactor: remove permissions for users, groups and invites

* test: adjust app router tests with app permissions

* fix: integration page accessible without session

* fix: search for users, groups and integrations shown to unauthenticated users

* chore: address pull request feedback
2024-11-17 21:31:25 +01:00

171 lines
4.5 KiB
TypeScript

import { Group, Text } from "@mantine/core";
import {
IconBox,
IconBrandDocker,
IconHome,
IconInfoSmall,
IconLayoutDashboard,
IconLogs,
IconMailForward,
IconPhoto,
IconPlug,
IconReport,
IconSearch,
IconSettings,
IconUsers,
IconUsersGroup,
} from "@tabler/icons-react";
import { useSession } from "@homarr/auth/client";
import { useScopedI18n } from "@homarr/translation/client";
import type { TablerIcon } from "@homarr/ui";
import { createGroup } from "../../lib/group";
import { interaction } from "../../lib/interaction";
export const pagesSearchGroup = createGroup<{
icon: TablerIcon;
name: string;
path: string;
}>({
keyPath: "path",
title: (t) => t("search.mode.page.group.page.title"),
Component: ({ name, icon: Icon }) => (
<Group px="md" py="sm">
<Icon stroke={1.5} />
<Text>{name}</Text>
</Group>
),
useInteraction: interaction.link(({ path }) => ({ href: path })),
filter: (query, { name, path }) => {
const normalizedQuery = query.trim().toLowerCase();
return name.toLowerCase().includes(normalizedQuery) || path.toLowerCase().includes(normalizedQuery);
},
sort: (query, options) => {
const normalizedQuery = query.trim().toLowerCase();
const nameMatches = options.map((option) => option.name.toLowerCase().includes(normalizedQuery));
const pathMatches = options.map((option) => option.path.toLowerCase().includes(normalizedQuery));
if (nameMatches.every(Boolean) && pathMatches.every(Boolean)) {
return 0;
}
if (nameMatches.every(Boolean) && !pathMatches.every(Boolean)) {
return pathMatches[0] ? -1 : 1;
}
return nameMatches[0] ? -1 : 1;
},
useOptions() {
const { data: session } = useSession();
const t = useScopedI18n("search.mode.page.group.page.option");
const managePages = [
{
icon: IconHome,
path: "/manage",
name: t("manageHome.label"),
},
{
icon: IconLayoutDashboard,
path: "/manage/boards",
name: t("manageBoard.label"),
},
{
icon: IconBox,
path: "/manage/apps",
name: t("manageApp.label"),
hidden: !session,
},
{
icon: IconPlug,
path: "/manage/integrations",
name: t("manageIntegration.label"),
hidden: !session,
},
{
icon: IconSearch,
path: "/manage/search-engines",
name: t("manageSearchEngine.label"),
hidden: !session,
},
{
icon: IconPhoto,
path: "/manage/medias",
name: t("manageMedia.label"),
hidden: !session,
},
{
icon: IconUsers,
path: "/manage/users",
name: t("manageUser.label"),
hidden: !session?.user.permissions.includes("admin"),
},
{
icon: IconMailForward,
path: "/manage/users/invites",
name: t("manageInvite.label"),
hidden: !session?.user.permissions.includes("admin"),
},
{
icon: IconUsersGroup,
path: "/manage/users/groups",
name: t("manageGroup.label"),
hidden: !session?.user.permissions.includes("admin"),
},
{
icon: IconBrandDocker,
path: "/manage/tools/docker",
name: "Manage Docker",
hidden: !session?.user.permissions.includes("admin"),
},
{
icon: IconPlug,
path: "/manage/tools/api",
name: t("manageApi.label"),
hidden: !session?.user.permissions.includes("admin"),
},
{
icon: IconLogs,
path: "/manage/tools/logs",
name: t("manageLog.label"),
hidden: !session?.user.permissions.includes("other-view-logs"),
},
{
icon: IconReport,
path: "/manage/tools/tasks",
name: t("manageTask.label"),
hidden: !session?.user.permissions.includes("admin"),
},
{
icon: IconSettings,
path: "/manage/settings",
name: t("manageSettings.label"),
hidden: !session?.user.permissions.includes("admin"),
},
{
icon: IconInfoSmall,
path: "/manage/about",
name: t("about.label"),
},
];
const otherPages = [
{
icon: IconHome,
path: "/boards",
name: t("homeBoard.label"),
},
{
icon: IconSettings,
path: `/manage/users/${session?.user.id}/general`,
name: t("preferences.label"),
hidden: !session,
},
];
return otherPages.concat(managePages).filter(({ hidden }) => !hidden);
},
});