From 3ef12cfe123bbf9984d3c4f35ee0b5e3a4a01582 Mon Sep 17 00:00:00 2001 From: Meier Lukas Date: Sun, 6 Aug 2023 15:40:19 +0200 Subject: [PATCH] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Update=20api=20endpoint=20?= =?UTF-8?q?authorization?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Manage/Board/create-board.modal.tsx | 2 +- .../Manage/Board/delete-board.modal.tsx | 2 +- src/pages/manage/boards/index.tsx | 68 +++++++++-------- src/server/api/routers/board.ts | 9 +-- src/server/api/routers/config.ts | 7 -- src/server/api/routers/docker/router.ts | 6 +- src/server/api/routers/weather.ts | 4 +- src/widgets/dnshole/DnsHoleControls.tsx | 74 +++++++++++-------- .../media-requests/MediaRequestListTile.tsx | 4 +- src/widgets/useNet/UseNetTile.tsx | 57 +++++++------- 10 files changed, 124 insertions(+), 109 deletions(-) diff --git a/src/components/Manage/Board/create-board.modal.tsx b/src/components/Manage/Board/create-board.modal.tsx index 56828266c..95919b05f 100644 --- a/src/components/Manage/Board/create-board.modal.tsx +++ b/src/components/Manage/Board/create-board.modal.tsx @@ -12,7 +12,7 @@ export const CreateBoardModal = ({ id }: ContextModalProps<{}>) => { const utils = api.useContext(); const { isLoading, mutate } = api.config.save.useMutation({ onSuccess: async () => { - await utils.config.all.invalidate(); + await utils.boards.all.invalidate(); modals.close(id); }, }); diff --git a/src/components/Manage/Board/delete-board.modal.tsx b/src/components/Manage/Board/delete-board.modal.tsx index 3124fa889..cddb7c9bb 100644 --- a/src/components/Manage/Board/delete-board.modal.tsx +++ b/src/components/Manage/Board/delete-board.modal.tsx @@ -10,7 +10,7 @@ export const DeleteBoardModal = ({ id, innerProps }: ContextModalProps { - await utils.config.all.invalidate(); + await utils.boards.all.invalidate(); modals.close(id); }, }); diff --git a/src/pages/manage/boards/index.tsx b/src/pages/manage/boards/index.tsx index c1fd95007..84dcb9b73 100644 --- a/src/pages/manage/boards/index.tsx +++ b/src/pages/manage/boards/index.tsx @@ -25,6 +25,7 @@ import { IconTrash, } from '@tabler/icons-react'; import { GetServerSideProps } from 'next'; +import { useSession } from 'next-auth/react'; import { useTranslation } from 'next-i18next'; import Head from 'next/head'; import Link from 'next/link'; @@ -39,6 +40,7 @@ import { api } from '~/utils/api'; const BoardsPage = () => { const context = api.useContext(); + const { data: sessionData } = useSession(); const { data } = api.boards.all.useQuery(); const { mutateAsync } = api.user.makeDefaultDashboard.useMutation({ onSettled: () => { @@ -60,13 +62,15 @@ const BoardsPage = () => { {t('pageTitle')} - + {sessionData?.user.isAdmin && ( + + )} {data && ( @@ -143,7 +147,7 @@ const BoardsPage = () => { > {t('cards.buttons.view')} - + @@ -160,28 +164,32 @@ const BoardsPage = () => { > {t('cards.menu.setAsDefault')} - - { - openDeleteBoardModal({ - boardName: board.name, - onConfirm: async () => { - append(board.name); - // give user feedback, that it's being deleted - await sleep(500); - filter((item, _) => item !== board.name); - }, - }); - }} - disabled={board.name === 'default'} - icon={} - color="red" - > - {t('cards.menu.delete.label')} - {board.name === 'default' && ( - {t('cards.menu.delete.disabled')} - )} - + {sessionData?.user.isAdmin && ( + <> + + { + openDeleteBoardModal({ + boardName: board.name, + onConfirm: async () => { + append(board.name); + // give user feedback, that it's being deleted + await sleep(500); + filter((item, _) => item !== board.name); + }, + }); + }} + disabled={board.name === 'default'} + icon={} + color="red" + > + {t('cards.menu.delete.label')} + {board.name === 'default' && ( + {t('cards.menu.delete.disabled')} + )} + + + )} diff --git a/src/server/api/routers/board.ts b/src/server/api/routers/board.ts index 0a4d25af6..2e6dc2bf2 100644 --- a/src/server/api/routers/board.ts +++ b/src/server/api/routers/board.ts @@ -1,17 +1,16 @@ import fs from 'fs'; +import { getFrontendConfig } from '~/tools/config/getFrontendConfig'; import { createTRPCRouter, protectedProcedure, publicProcedure } from '../trpc'; -import { getFrontendConfig } from '~/tools/config/getFrontendConfig'; - export const boardRouter = createTRPCRouter({ all: protectedProcedure.query(async ({ ctx }) => { const files = fs.readdirSync('./data/configs').filter((file) => file.endsWith('.json')); const userSettings = await ctx.prisma.userSettings.findUniqueOrThrow({ where: { - userId: ctx.session?.user.id - } + userId: ctx.session?.user.id, + }, }); return await Promise.all( @@ -26,7 +25,7 @@ export const boardRouter = createTRPCRouter({ countApps: countApps, countWidgets: config.widgets.length, countCategories: config.categories.length, - isDefaultForUser: name === userSettings.defaultBoard + isDefaultForUser: name === userSettings.defaultBoard, }; }) ); diff --git a/src/server/api/routers/config.ts b/src/server/api/routers/config.ts index 072224155..93724bca6 100644 --- a/src/server/api/routers/config.ts +++ b/src/server/api/routers/config.ts @@ -16,13 +16,6 @@ import { adminProcedure, createTRPCRouter, publicProcedure } from '../trpc'; const configNameSchema = z.string().regex(/^[a-zA-Z0-9-_]+$/); export const configRouter = createTRPCRouter({ - all: publicProcedure.query(async () => { - // Get all the configs in the /data/configs folder - // All the files that end in ".json" - const files = fs.readdirSync('./data/configs').filter((file) => file.endsWith('.json')); - // Strip the .json extension from the file name - return files.map((file) => file.replace('.json', '')); - }), delete: adminProcedure .input( z.object({ diff --git a/src/server/api/routers/docker/router.ts b/src/server/api/routers/docker/router.ts index b1fb5fa78..942d31b05 100644 --- a/src/server/api/routers/docker/router.ts +++ b/src/server/api/routers/docker/router.ts @@ -2,13 +2,13 @@ import { TRPCError } from '@trpc/server'; import Dockerode from 'dockerode'; import { z } from 'zod'; -import { createTRPCRouter, publicProcedure } from '../../trpc'; +import { adminProcedure, createTRPCRouter } from '../../trpc'; import DockerSingleton from './DockerSingleton'; const dockerActionSchema = z.enum(['remove', 'start', 'stop', 'restart']); export const dockerRouter = createTRPCRouter({ - containers: publicProcedure.query(async () => { + containers: adminProcedure.query(async () => { try { const docker = DockerSingleton.getInstance(); const containers = await docker.listContainers({ all: true }); @@ -20,7 +20,7 @@ export const dockerRouter = createTRPCRouter({ }); } }), - action: publicProcedure + action: adminProcedure .input( z.object({ id: z.string(), diff --git a/src/server/api/routers/weather.ts b/src/server/api/routers/weather.ts index 1f9e34a16..124f42d45 100644 --- a/src/server/api/routers/weather.ts +++ b/src/server/api/routers/weather.ts @@ -1,6 +1,6 @@ import { z } from 'zod'; -import { createTRPCRouter, publicProcedure } from '../trpc'; +import { adminProcedure, createTRPCRouter, publicProcedure } from '../trpc'; const citySchema = z.object({ id: z.number(), @@ -24,7 +24,7 @@ const weatherSchema = z.object({ }); export const weatherRouter = createTRPCRouter({ - findCity: publicProcedure + findCity: adminProcedure .input( z.object({ query: z.string().min(2), diff --git a/src/widgets/dnshole/DnsHoleControls.tsx b/src/widgets/dnshole/DnsHoleControls.tsx index dbd7a6b19..0d7444a46 100644 --- a/src/widgets/dnshole/DnsHoleControls.tsx +++ b/src/widgets/dnshole/DnsHoleControls.tsx @@ -1,11 +1,11 @@ import { Badge, Box, Button, Card, Group, Image, SimpleGrid, Stack, Text } from '@mantine/core'; import { useElementSize } from '@mantine/hooks'; import { IconDeviceGamepad, IconPlayerPlay, IconPlayerStop } from '@tabler/icons-react'; +import { useSession } from 'next-auth/react'; import { useTranslation } from 'next-i18next'; import { api } from '~/utils/api'; import { useConfigContext } from '../../config/provider'; -import { queryClient } from '../../tools/server/configurations/tanstack/queryClient.tool'; import { defineWidget } from '../helper'; import { WidgetLoading } from '../loading'; import { IWidget } from '../widgets'; @@ -32,6 +32,8 @@ interface DnsHoleControlsWidgetProps { } function DnsHoleControlsWidgetTile({ widget }: DnsHoleControlsWidgetProps) { + const utils = api.useContext(); + const { data: sessionData } = useSession(); const { isInitialLoading, data } = useDnsHoleSummeryQuery(); const { mutateAsync } = useDnsHoleControlMutation(); const { width, ref } = useElementSize(); @@ -45,38 +47,46 @@ function DnsHoleControlsWidgetTile({ widget }: DnsHoleControlsWidgetProps) { return ( - 275 ? 2 : 1} verticalSpacing="0.25rem" spacing="0.25rem"> - - - + + + + )} {data.status.map((status, index) => { diff --git a/src/widgets/media-requests/MediaRequestListTile.tsx b/src/widgets/media-requests/MediaRequestListTile.tsx index 512dbe45d..ae853a73b 100644 --- a/src/widgets/media-requests/MediaRequestListTile.tsx +++ b/src/widgets/media-requests/MediaRequestListTile.tsx @@ -12,6 +12,7 @@ import { } from '@mantine/core'; import { notifications } from '@mantine/notifications'; import { IconCheck, IconGitPullRequest, IconThumbDown, IconThumbUp } from '@tabler/icons-react'; +import { useSession } from 'next-auth/react'; import { useTranslation } from 'next-i18next'; import { useConfigContext } from '~/config/provider'; import { api } from '~/utils/api'; @@ -95,6 +96,7 @@ function MediaRequestListTile({ widget }: MediaRequestListWidgetProps) { const { data, isLoading } = useMediaRequestQuery(); // Use mutation to approve or deny a pending request const decideAsync = useMediaRequestDecisionMutation(); + const { data: sessionData } = useSession(); if (!data || isLoading) { return ; @@ -177,7 +179,7 @@ function MediaRequestListTile({ widget }: MediaRequestListWidgetProps) { - {item.status === MediaRequestStatus.PendingApproval && ( + {item.status === MediaRequestStatus.PendingApproval && sessionData?.user?.isAdmin && ( x.integration && downloadAppTypes.includes(x.integration.type)) ?? []; - const { ref, width, height } = useElementSize(); + const { ref, width } = useElementSize(); + const { data: sessionData } = useSession(); const [selectedAppId, setSelectedApp] = useState(downloadApps[0]?.id); const { data } = useGetUsenetInfo({ appId: selectedAppId! }); @@ -106,30 +108,31 @@ function UseNetTile({ widget }: UseNetTileProps) { )} - {!data ? null : data.paused ? ( - - ) : ( - - )} + {sessionData?.user?.isAdmin && + (!data ? null : data.paused ? ( + + ) : ( + + ))}