fix: workspace settings access validation updated (#5606)

This commit is contained in:
Anmol Singh Bhatia 2024-09-16 14:03:06 +05:30 committed by GitHub
parent f155a13929
commit c14d20c2e0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 57 additions and 33 deletions

View file

@ -1,34 +1,51 @@
"use client"; "use client";
import { ReactNode } from "react"; import { FC, ReactNode } from "react";
import { observer } from "mobx-react";
// components // components
import { AppHeader } from "@/components/core"; import { AppHeader } from "@/components/core";
// local components // local components
import { WorkspaceSettingHeader } from "./header"; import { WorkspaceSettingHeader } from "./header";
import { MobileWorkspaceSettingsTabs } from "./mobile-header-tabs"; import { MobileWorkspaceSettingsTabs } from "./mobile-header-tabs";
import { WorkspaceSettingsSidebar } from "./sidebar"; import { WorkspaceSettingsSidebar } from "./sidebar";
import { NotAuthorizedView } from "@/components/auth-screens";
import { useUserPermissions } from "@/hooks/store";
import { EUserPermissions, EUserPermissionsLevel } from "@/plane-web/constants/user-permissions";
export interface IWorkspaceSettingLayout { export interface IWorkspaceSettingLayout {
children: ReactNode; children: ReactNode;
} }
export default function WorkspaceSettingLayout(props: IWorkspaceSettingLayout) { const WorkspaceSettingLayout: FC<IWorkspaceSettingLayout> = observer((props) => {
const { children } = props; const { children } = props;
const { workspaceUserInfo, allowPermissions } = useUserPermissions();
// derived values
const isWorkspaceAdmin = allowPermissions([EUserPermissions.ADMIN], EUserPermissionsLevel.WORKSPACE);
return ( return (
<> <>
<AppHeader header={<WorkspaceSettingHeader />} /> <AppHeader header={<WorkspaceSettingHeader />} />
<MobileWorkspaceSettingsTabs /> <MobileWorkspaceSettingsTabs />
<div className="inset-y-0 flex flex-row vertical-scrollbar scrollbar-lg h-full w-full overflow-y-auto"> <div className="inset-y-0 flex flex-row vertical-scrollbar scrollbar-lg h-full w-full overflow-y-auto">
<div className="px-page-x !pr-0 py-page-y flex-shrink-0 overflow-y-hidden sm:hidden hidden md:block lg:block"> {workspaceUserInfo && !isWorkspaceAdmin ? (
<WorkspaceSettingsSidebar /> <NotAuthorizedView section="settings" />
</div> ) : (
<div className="flex flex-col relative w-full overflow-hidden"> <>
<div className="w-full h-full overflow-x-hidden overflow-y-scroll vertical-scrollbar scrollbar-md px-page-x md:px-9 py-page-y"> <div className="px-page-x !pr-0 py-page-y flex-shrink-0 overflow-y-hidden sm:hidden hidden md:block lg:block">
{children} <WorkspaceSettingsSidebar />
</div> </div>
</div> <div className="flex flex-col relative w-full overflow-hidden">
<div className="w-full h-full overflow-x-hidden overflow-y-scroll vertical-scrollbar scrollbar-md px-page-x md:px-9 py-page-y">
{children}
</div>
</div>
</>
)}
</div> </div>
</> </>
); );
} });
export default WorkspaceSettingLayout;

View file

@ -9,7 +9,7 @@ export const WORKSPACE_SETTINGS = {
key: "general", key: "general",
label: "General", label: "General",
href: `/settings`, href: `/settings`,
access: [EUserPermissions.ADMIN, EUserPermissions.MEMBER, EUserPermissions.GUEST], access: [EUserPermissions.ADMIN],
highlight: (pathname: string, baseUrl: string) => pathname === `${baseUrl}/settings/`, highlight: (pathname: string, baseUrl: string) => pathname === `${baseUrl}/settings/`,
Icon: SettingIcon, Icon: SettingIcon,
}, },
@ -17,7 +17,7 @@ export const WORKSPACE_SETTINGS = {
key: "members", key: "members",
label: "Members", label: "Members",
href: `/settings/members`, href: `/settings/members`,
access: [EUserPermissions.ADMIN, EUserPermissions.MEMBER], access: [EUserPermissions.ADMIN],
highlight: (pathname: string, baseUrl: string) => pathname === `${baseUrl}/settings/members/`, highlight: (pathname: string, baseUrl: string) => pathname === `${baseUrl}/settings/members/`,
Icon: SettingIcon, Icon: SettingIcon,
}, },

View file

@ -15,7 +15,8 @@ import { IWorkspace } from "@plane/types";
import { Avatar, Loader, TOAST_TYPE, setToast } from "@plane/ui"; import { Avatar, Loader, TOAST_TYPE, setToast } from "@plane/ui";
import { GOD_MODE_URL, cn } from "@/helpers/common.helper"; import { GOD_MODE_URL, cn } from "@/helpers/common.helper";
// hooks // hooks
import { useAppTheme, useUser, useUserProfile, useWorkspace } from "@/hooks/store"; import { useAppTheme, useUser, useUserPermissions, useUserProfile, useWorkspace } from "@/hooks/store";
import { EUserPermissions, EUserPermissionsLevel } from "@/plane-web/constants/user-permissions";
import { WorkspaceLogo } from "../logo"; import { WorkspaceLogo } from "../logo";
// Static Data // Static Data
@ -25,12 +26,14 @@ const userLinks = (workspaceSlug: string) => [
name: "Workspace invites", name: "Workspace invites",
href: "/invitations", href: "/invitations",
icon: Mails, icon: Mails,
access: [EUserPermissions.ADMIN, EUserPermissions.MEMBER, EUserPermissions.GUEST],
}, },
{ {
key: "settings", key: "settings",
name: "Workspace settings", name: "Workspace settings",
href: `/${workspaceSlug}/settings`, href: `/${workspaceSlug}/settings`,
icon: Settings, icon: Settings,
access: [EUserPermissions.ADMIN],
}, },
]; ];
@ -46,6 +49,7 @@ export const SidebarDropdown = observer(() => {
signOut, signOut,
} = useUser(); } = useUser();
const { updateUserProfile } = useUserProfile(); const { updateUserProfile } = useUserProfile();
const { allowPermissions } = useUserPermissions();
const isUserInstanceAdmin = false; const isUserInstanceAdmin = false;
const { currentWorkspace: activeWorkspace, workspaces } = useWorkspace(); const { currentWorkspace: activeWorkspace, workspaces } = useWorkspace();
@ -168,7 +172,7 @@ export const SidebarDropdown = observer(() => {
alt="Workspace Logo" alt="Workspace Logo"
/> />
) : ( ) : (
workspace?.name?.charAt(0) ?? "..." (workspace?.name?.charAt(0) ?? "...")
)} )}
</span> </span>
<h5 <h5
@ -207,24 +211,27 @@ export const SidebarDropdown = observer(() => {
Create workspace Create workspace
</Menu.Item> </Menu.Item>
</Link> </Link>
{userLinks(workspaceSlug?.toString() ?? "").map((link, index) => ( {userLinks(workspaceSlug?.toString() ?? "").map(
<Link (link, index) =>
key={link.key} allowPermissions(link.access, EUserPermissionsLevel.WORKSPACE) && (
href={link.href} <Link
className="w-full" key={link.key}
onClick={() => { href={link.href}
if (index > 0) handleItemClick(); className="w-full"
}} onClick={() => {
> if (index > 0) handleItemClick();
<Menu.Item }}
as="div" >
className="flex items-center gap-2 rounded px-2 py-1 text-sm font-medium text-custom-sidebar-text-200 hover:bg-custom-sidebar-background-80" <Menu.Item
> as="div"
<link.icon className="h-4 w-4 flex-shrink-0" /> className="flex items-center gap-2 rounded px-2 py-1 text-sm font-medium text-custom-sidebar-text-200 hover:bg-custom-sidebar-background-80"
{link.name} >
</Menu.Item> <link.icon className="h-4 w-4 flex-shrink-0" />
</Link> {link.name}
))} </Menu.Item>
</Link>
)
)}
</div> </div>
<div className="w-full px-4 py-2"> <div className="w-full px-4 py-2">
<Menu.Item <Menu.Item