SECURITY - МЕЖПРОЕКТНАЯ КОММУНИКАЦИЯ: ограничение создания проектов

This commit is contained in:
DCCONSTRUCTIONS
2026-05-12 22:24:36 +03:00
parent 87e1857f53
commit 5e7c9e08a0
18 changed files with 251 additions and 70 deletions
@@ -42,7 +42,7 @@ export const NoProjectsEmptyState = observer(function NoProjectsEmptyState() {
const { t } = useTranslation();
// derived values
const canCreateProject = allowPermissions(
[EUserPermissions.ADMIN, EUserPermissions.MEMBER],
[EUserPermissions.ADMIN],
EUserPermissionsLevel.WORKSPACE
);
const isWorkspaceAdmin = allowPermissions([EUserPermissions.ADMIN], EUserPermissionsLevel.WORKSPACE);
@@ -23,6 +23,7 @@ export const GlobalViewEmptyState = observer(function GlobalViewEmptyState() {
const { toggleCreateIssueModal, toggleCreateProjectModal } = useCommandPalette();
const { allowPermissions } = useUserPermissions();
// derived values
const canCreateProject = allowPermissions([EUserWorkspaceRoles.ADMIN], EUserPermissionsLevel.WORKSPACE);
const hasMemberLevelPermission = allowPermissions(
[EUserWorkspaceRoles.ADMIN, EUserWorkspaceRoles.MEMBER],
EUserPermissionsLevel.WORKSPACE
@@ -41,7 +42,7 @@ export const GlobalViewEmptyState = observer(function GlobalViewEmptyState() {
onClick: () => {
toggleCreateProjectModal(true);
},
disabled: !hasMemberLevelPermission,
disabled: !canCreateProject,
variant: "primary",
},
]}
@@ -39,10 +39,7 @@ export const WorkspaceDraftIssuesRoot = observer(function WorkspaceDraftIssuesRo
const { toggleCreateProjectModal } = useCommandPalette();
const { allowPermissions } = useUserPermissions();
// derived values
const hasMemberLevelPermission = allowPermissions(
[EUserWorkspaceRoles.ADMIN, EUserWorkspaceRoles.MEMBER],
EUserPermissionsLevel.WORKSPACE
);
const canCreateProject = allowPermissions([EUserWorkspaceRoles.ADMIN], EUserPermissionsLevel.WORKSPACE);
//swr hook for fetching issue properties
useWorkspaceIssueProperties(workspaceSlug);
@@ -77,7 +74,7 @@ export const WorkspaceDraftIssuesRoot = observer(function WorkspaceDraftIssuesRo
onClick: () => {
toggleCreateProjectModal(true);
},
disabled: !hasMemberLevelPermission,
disabled: !canCreateProject,
variant: "primary",
},
]}
@@ -48,7 +48,7 @@ export const usePowerKCreationCommandsRecord = (): Record<TPowerKCreationCommand
// derived values
const canCreateWorkItem = canPerformAnyCreateAction && workspaceProjectIds && workspaceProjectIds.length > 0;
const canCreateProject = allowPermissions(
[EUserPermissions.ADMIN, EUserPermissions.MEMBER],
[EUserPermissions.ADMIN],
EUserPermissionsLevel.WORKSPACE
);
const hasProjectMemberLevelPermissions = (ctx: TPowerKContext) =>
@@ -48,7 +48,7 @@ export const ProjectCardList = observer(function ProjectCardList(props: TProject
// permissions
const canPerformEmptyStateActions = allowPermissions(
[EUserPermissions.ADMIN, EUserPermissions.MEMBER],
[EUserPermissions.ADMIN],
EUserPermissionsLevel.WORKSPACE
);
@@ -5,12 +5,14 @@
*/
import { useEffect, useState } from "react";
import { EUserPermissions, EUserPermissionsLevel } from "@plane/constants";
import { EModalPosition, EModalWidth, ModalCore } from "@plane/ui";
import { getAssetIdFromUrl, checkURLValidity } from "@plane/utils";
// plane ui
// helpers
// hooks
import useKeypress from "@/hooks/use-keypress";
import { useUserPermissions } from "@/hooks/store/user";
// plane web components
import { CreateProjectForm } from "@/plane-web/components/projects/create/root";
// plane web types
@@ -36,9 +38,11 @@ enum EProjectCreationSteps {
export function CreateProjectModal(props: Props) {
const { isOpen, onClose, setToFavorite = false, workspaceSlug, data, templateId } = props;
const { allowPermissions } = useUserPermissions();
// states
const [currentStep, setCurrentStep] = useState<EProjectCreationSteps>(EProjectCreationSteps.CREATE_PROJECT);
const [createdProjectId, setCreatedProjectId] = useState<string | null>(null);
const canCreateProject = allowPermissions([EUserPermissions.ADMIN], EUserPermissionsLevel.WORKSPACE, workspaceSlug);
useEffect(() => {
if (isOpen) {
@@ -47,6 +51,10 @@ export function CreateProjectModal(props: Props) {
}
}, [isOpen]);
useEffect(() => {
if (isOpen && !canCreateProject) onClose();
}, [canCreateProject, isOpen, onClose]);
const handleNextStep = (projectId: string) => {
if (!projectId) return;
setCreatedProjectId(projectId);
@@ -65,6 +73,8 @@ export function CreateProjectModal(props: Props) {
if (isOpen) onClose();
});
if (!canCreateProject) return null;
return (
<ModalCore
isOpen={isOpen}
@@ -33,7 +33,7 @@ export const ProjectsBaseHeader = observer(function ProjectsBaseHeader() {
const pathname = usePathname();
// auth
const isAuthorizedUser = allowPermissions(
[EUserPermissions.ADMIN, EUserPermissions.MEMBER],
[EUserPermissions.ADMIN],
EUserPermissionsLevel.WORKSPACE
);
const isArchived = pathname.includes("/archives");
@@ -55,7 +55,7 @@ export const SidebarProjectsList = observer(function SidebarProjectsList() {
// auth
const isAuthorizedUser = allowPermissions(
[EUserPermissions.ADMIN, EUserPermissions.MEMBER],
[EUserPermissions.ADMIN],
EUserPermissionsLevel.WORKSPACE
);