refactor(cloud): add validation to prevent access to shared resources

This commit is contained in:
Mauricio Siu
2024-10-04 20:44:57 -06:00
parent 5cebf5540a
commit 7c4987d84d
14 changed files with 353 additions and 146 deletions

View File

@@ -11,7 +11,6 @@ import {
import { Input } from "@/components/ui/input";
import { Switch } from "@/components/ui/switch";
import { api } from "@/utils/api";
import { useUrl } from "@/utils/hooks/use-url";
import { format } from "date-fns";
import { useEffect, useState } from "react";

View File

@@ -11,6 +11,7 @@ interface TabInfo {
tabLabel?: string;
description: string;
index: string;
type: TabState;
isShow?: ({ rol, user }: { rol?: Auth["rol"]; user?: User }) => boolean;
}
@@ -23,19 +24,24 @@ export type TabState =
| "docker";
const getTabMaps = (isCloud: boolean) => {
const tabMap: Record<TabState | undefined, TabInfo> = {
projects: {
const elements: TabInfo[] = [
{
label: "Projects",
description: "Manage your projects",
index: "/dashboard/projects",
type: "projects",
},
...(!isCloud && {
monitoring: {
];
if (!isCloud) {
elements.push(
{
label: "Monitoring",
description: "Monitor your projects",
index: "/dashboard/monitoring",
type: "monitoring",
},
traefik: {
{
label: "Traefik",
tabLabel: "Traefik File System",
description: "Manage your traefik",
@@ -43,35 +49,39 @@ const getTabMaps = (isCloud: boolean) => {
isShow: ({ rol, user }) => {
return Boolean(rol === "admin" || user?.canAccessToTraefikFiles);
},
type: "traefik",
},
docker: {
{
label: "Docker",
description: "Manage your docker",
index: "/dashboard/docker",
isShow: ({ rol, user }) => {
return Boolean(rol === "admin" || user?.canAccessToDocker);
},
type: "docker",
},
requests: {
{
label: "Requests",
description: "Manage your requests",
index: "/dashboard/requests",
isShow: ({ rol, user }) => {
return Boolean(rol === "admin" || user?.canAccessToDocker);
},
type: "requests",
},
}),
);
}
settings: {
label: "Settings",
description: "Manage your settings",
index: isCloud
? "/dashboard/settings/profile"
: "/dashboard/settings/server",
},
};
elements.push({
label: "Settings",
description: "Manage your settings",
type: "settings",
index: isCloud
? "/dashboard/settings/profile"
: "/dashboard/settings/server",
});
return tabMap;
return elements;
};
interface Props {
@@ -99,7 +109,7 @@ export const NavigationTabs = ({ tab, children }: Props) => {
}, [tab]);
const activeTabInfo = useMemo(() => {
return tabMap[activeTab];
return tabMap.find((tab) => tab.type === activeTab);
}, [activeTab]);
return (
@@ -107,10 +117,10 @@ export const NavigationTabs = ({ tab, children }: Props) => {
<header className="mb-6 flex w-full items-center gap-2 justify-between flex-wrap">
<div className="flex flex-col gap-2">
<h1 className="text-xl font-bold lg:text-3xl">
{activeTabInfo.label}
{activeTabInfo?.label}
</h1>
<p className="lg:text-medium text-muted-foreground">
{activeTabInfo.description}
{activeTabInfo?.description}
</p>
</div>
{tab === "projects" &&
@@ -122,27 +132,26 @@ export const NavigationTabs = ({ tab, children }: Props) => {
className="w-full"
onValueChange={async (e) => {
setActiveTab(e as TabState);
router.push(tabMap[e as TabState].index);
const tab = tabMap.find((tab) => tab.type === e);
router.push(tab?.index || "");
}}
>
{/* className="grid w-fit grid-cols-4 bg-transparent" */}
<div className="flex flex-row items-center justify-between w-full gap-4 max-sm:overflow-x-auto border-b border-b-divider pb-1">
<TabsList className="bg-transparent relative px-0">
{Object.keys(tabMap).map((key) => {
const tab = tabMap[key as TabState];
if (tab.isShow && !tab.isShow?.({ rol: data?.rol, user })) {
{tabMap.map((tab, index) => {
if (tab?.isShow && !tab?.isShow?.({ rol: data?.rol, user })) {
return null;
}
return (
<TabsTrigger
key={key}
value={key}
key={tab.type}
value={tab.type}
className="relative py-2.5 md:px-5 data-[state=active]:shadow-none data-[state=active]:bg-transparent rounded-md hover:bg-zinc-100 hover:dark:bg-zinc-800 data-[state=active]:hover:bg-zinc-100 data-[state=active]:hover:dark:bg-zinc-800"
>
<span className="relative z-[1] w-full">
{tab.tabLabel || tab.label}
{tab?.tabLabel || tab?.label}
</span>
{key === activeTab && (
{tab.type === activeTab && (
<div className="absolute -bottom-[5.5px] w-full">
<div className="h-0.5 bg-foreground rounded-t-md" />
</div>

View File

@@ -48,12 +48,16 @@ export const SettingsLayout = ({ children }: Props) => {
icon: Database,
href: "/dashboard/settings/destinations",
},
{
title: "Certificates",
label: "",
icon: ShieldCheck,
href: "/dashboard/settings/certificates",
},
...(!isCloud
? [
{
title: "Certificates",
label: "",
icon: ShieldCheck,
href: "/dashboard/settings/certificates",
},
]
: []),
{
title: "SSH Keys",
label: "",