diff --git a/backend/src/controllers/v1/organizationController.ts b/backend/src/controllers/v1/organizationController.ts index edd57a3b8..757d1aed7 100644 --- a/backend/src/controllers/v1/organizationController.ts +++ b/backend/src/controllers/v1/organizationController.ts @@ -8,7 +8,7 @@ import { } from "../../models"; import { createOrganization as create } from "../../helpers/organization"; import { addMembershipsOrg } from "../../helpers/membershipOrg"; -import { ACCEPTED, OWNER } from "../../variables"; +import { ACCEPTED, ADMIN } from "../../variables"; import { getLicenseServerUrl, getSiteURL } from "../../config"; import { licenseServerKeyRequest } from "../../config/request"; import { validateRequest } from "../../helpers/validation"; @@ -55,7 +55,7 @@ export const createOrganization = async (req: Request, res: Response) => { await addMembershipsOrg({ userIds: [req.user._id.toString()], organizationId: organization._id.toString(), - roles: [OWNER], + roles: [ADMIN], statuses: [ACCEPTED] }); diff --git a/backend/src/controllers/v3/secretsController.ts b/backend/src/controllers/v3/secretsController.ts index fad50b0ca..a528436af 100644 --- a/backend/src/controllers/v3/secretsController.ts +++ b/backend/src/controllers/v3/secretsController.ts @@ -55,6 +55,9 @@ export const getSecretsRaw = async (req: Request, res: Response) => { secretPath = getFolderWithPathFromId(folder.nodes, folderId).folderPath; } + if (!environment || !workspaceId) + throw BadRequestError({ message: "Missing environment or workspace id" }); + let permissionCheckFn: (env: string, secPath: string) => boolean; // used to pass as callback function to import secret if (req.user?._id) { const { permission } = await getUserProjectPermissions(req.user._id, workspaceId); diff --git a/backend/src/ee/controllers/v1/roleController.ts b/backend/src/ee/controllers/v1/roleController.ts index 2c87b9ff8..0d5f105ea 100644 --- a/backend/src/ee/controllers/v1/roleController.ts +++ b/backend/src/ee/controllers/v1/roleController.ts @@ -171,18 +171,6 @@ export const getRoles = async (req: Request, res: Response) => { const customRoles = await Role.find({ organization: orgId, isOrgRole, workspace: workspaceId }); // as this is shared between org and workspace switch the rule set based on it const roles = [ - // owner is only in org level role - ...(isOrgRole - ? [ - { - _id: "owner", - name: "Owner", - slug: "owner", - description: "Complete administration access over the organization.", - permissions: adminPermissions.rules - } - ] - : []), { _id: "admin", name: "Admin", @@ -192,7 +180,7 @@ export const getRoles = async (req: Request, res: Response) => { }, { _id: "member", - name: "Member", + name: isOrgRole ? "Member" : "Developer", slug: "member", description: "Non-administrative role in an organization", permissions: isOrgRole ? memberPermissions.rules : memberProjectPermissions.rules diff --git a/backend/src/ee/controllers/v1/workspaceController.ts b/backend/src/ee/controllers/v1/workspaceController.ts index 14ea8978d..7c9502656 100644 --- a/backend/src/ee/controllers/v1/workspaceController.ts +++ b/backend/src/ee/controllers/v1/workspaceController.ts @@ -1,6 +1,14 @@ import { Request, Response } from "express"; import { PipelineStage, Types } from "mongoose"; -import { Folder, Membership, Secret, ServiceTokenData, TFolderSchema, User } from "../../../models"; +import { + Folder, + Membership, + Secret, + ServiceTokenData, + TFolderSchema, + User, + Workspace +} from "../../../models"; import { ActorType, AuditLog, @@ -41,6 +49,7 @@ import { getUserProjectPermissions } from "../../services/ProjectRoleService"; import { ForbiddenError } from "@casl/ability"; +import { BadRequestError } from "../../../utils/errors"; /** * Return secret snapshots for workspace with id [workspaceId] @@ -781,7 +790,10 @@ export const addWorkspaceTrustedIp = async (req: Request, res: Response) => { ProjectPermissionSub.IpAllowList ); - const plan = await EELicenseService.getPlan(req.workspace.organization); + const workspace = await Workspace.findById(workspaceId); + if (!workspace) throw BadRequestError({ message: "Workspace not found" }); + + const plan = await EELicenseService.getPlan(workspace.organization); if (!plan.ipAllowlisting) return res.status(400).send({ @@ -844,7 +856,10 @@ export const updateWorkspaceTrustedIp = async (req: Request, res: Response) => { ProjectPermissionSub.IpAllowList ); - const plan = await EELicenseService.getPlan(req.workspace.organization); + const workspace = await Workspace.findById(workspaceId); + if (!workspace) throw BadRequestError({ message: "Workspace not found" }); + + const plan = await EELicenseService.getPlan(workspace.organization); if (!plan.ipAllowlisting) return res.status(400).send({ @@ -933,7 +948,10 @@ export const deleteWorkspaceTrustedIp = async (req: Request, res: Response) => { ProjectPermissionSub.IpAllowList ); - const plan = await EELicenseService.getPlan(req.workspace.organization); + const workspace = await Workspace.findById(workspaceId); + if (!workspace) throw BadRequestError({ message: "Workspace not found" }); + + const plan = await EELicenseService.getPlan(workspace.organization); if (!plan.ipAllowlisting) return res.status(400).send({ diff --git a/backend/src/ee/services/ProjectRoleService.ts b/backend/src/ee/services/ProjectRoleService.ts index 26491fab2..51f4a26f1 100644 --- a/backend/src/ee/services/ProjectRoleService.ts +++ b/backend/src/ee/services/ProjectRoleService.ts @@ -158,13 +158,39 @@ const buildMemberPermission = () => { can(ProjectPermissionActions.Create, ProjectPermissionSub.SecretRollback); can(ProjectPermissionActions.Read, ProjectPermissionSub.Member); - can(ProjectPermissionActions.Read, ProjectPermissionSub.Role); + can(ProjectPermissionActions.Create, ProjectPermissionSub.Member); + can(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations); + can(ProjectPermissionActions.Create, ProjectPermissionSub.Integrations); + can(ProjectPermissionActions.Edit, ProjectPermissionSub.Integrations); + can(ProjectPermissionActions.Delete, ProjectPermissionSub.Integrations); + can(ProjectPermissionActions.Read, ProjectPermissionSub.Webhooks); + can(ProjectPermissionActions.Create, ProjectPermissionSub.Webhooks); + can(ProjectPermissionActions.Edit, ProjectPermissionSub.Webhooks); + can(ProjectPermissionActions.Delete, ProjectPermissionSub.Webhooks); + can(ProjectPermissionActions.Read, ProjectPermissionSub.ServiceTokens); + can(ProjectPermissionActions.Create, ProjectPermissionSub.ServiceTokens); + can(ProjectPermissionActions.Edit, ProjectPermissionSub.ServiceTokens); + can(ProjectPermissionActions.Delete, ProjectPermissionSub.ServiceTokens); + can(ProjectPermissionActions.Read, ProjectPermissionSub.Settings); + can(ProjectPermissionActions.Create, ProjectPermissionSub.Settings); + can(ProjectPermissionActions.Edit, ProjectPermissionSub.Settings); + can(ProjectPermissionActions.Delete, ProjectPermissionSub.Settings); + can(ProjectPermissionActions.Read, ProjectPermissionSub.Environments); + can(ProjectPermissionActions.Create, ProjectPermissionSub.Environments); + can(ProjectPermissionActions.Edit, ProjectPermissionSub.Environments); + can(ProjectPermissionActions.Delete, ProjectPermissionSub.Environments); + can(ProjectPermissionActions.Read, ProjectPermissionSub.Tags); + can(ProjectPermissionActions.Create, ProjectPermissionSub.Tags); + can(ProjectPermissionActions.Edit, ProjectPermissionSub.Tags); + can(ProjectPermissionActions.Delete, ProjectPermissionSub.Tags); + + can(ProjectPermissionActions.Read, ProjectPermissionSub.Role); can(ProjectPermissionActions.Read, ProjectPermissionSub.AuditLogs); can(ProjectPermissionActions.Read, ProjectPermissionSub.IpAllowList); diff --git a/backend/src/ee/services/RoleService.ts b/backend/src/ee/services/RoleService.ts index df5ebf29a..8f8c4f315 100644 --- a/backend/src/ee/services/RoleService.ts +++ b/backend/src/ee/services/RoleService.ts @@ -86,12 +86,17 @@ const buildMemberPermission = () => { can(OrgPermissionActions.Read, OrgPermissionSubjects.Workspace); can(OrgPermissionActions.Create, OrgPermissionSubjects.Workspace); can(OrgPermissionActions.Read, OrgPermissionSubjects.Member); + can(OrgPermissionActions.Create, OrgPermissionSubjects.Member); can(OrgPermissionActions.Read, OrgPermissionSubjects.Role); can(OrgPermissionActions.Read, OrgPermissionSubjects.Settings); can(OrgPermissionActions.Read, OrgPermissionSubjects.Billing); can(OrgPermissionActions.Read, OrgPermissionSubjects.Sso); can(OrgPermissionActions.Read, OrgPermissionSubjects.IncidentAccount); + can(OrgPermissionActions.Read, OrgPermissionSubjects.SecretScanning); + can(OrgPermissionActions.Create, OrgPermissionSubjects.SecretScanning); + can(OrgPermissionActions.Edit, OrgPermissionSubjects.SecretScanning); + can(OrgPermissionActions.Delete, OrgPermissionSubjects.SecretScanning); return build({ conditionsMatcher }); }; @@ -114,8 +119,7 @@ export const getUserOrgPermissions = async (userId: string, orgId: string) => { throw UnauthorizedRequestError({ message: "User doesn't belong to organization" }); } - if (membership.role === "admin" || membership.role === "owner") - return { permission: adminPermissions, membership }; + if (membership.role === "admin") return { permission: adminPermissions, membership }; if (membership.role === "member") return { permission: memberPermissions, membership }; diff --git a/backend/src/helpers/signup.ts b/backend/src/helpers/signup.ts index da494f4f7..27b1c16ab 100644 --- a/backend/src/helpers/signup.ts +++ b/backend/src/helpers/signup.ts @@ -1,7 +1,7 @@ import { IUser } from "../models"; import { createOrganization } from "./organization"; import { addMembershipsOrg } from "./membershipOrg"; -import { ACCEPTED, OWNER } from "../variables"; +import { ACCEPTED, ADMIN } from "../variables"; import { sendMail } from "../helpers/nodemailer"; import { TokenService } from "../services"; import { TOKEN_EMAIL_CONFIRMATION } from "../variables"; @@ -14,10 +14,10 @@ import { TOKEN_EMAIL_CONFIRMATION } from "../variables"; * @returns {Boolean} success - whether or not operation was successful */ export const sendEmailVerification = async ({ email }: { email: string }) => { - const token = await TokenService.createToken({ - type: TOKEN_EMAIL_CONFIRMATION, - email, - }); + const token = await TokenService.createToken({ + type: TOKEN_EMAIL_CONFIRMATION, + email + }); // send mail await sendMail({ @@ -25,8 +25,8 @@ export const sendEmailVerification = async ({ email }: { email: string }) => { subjectLine: "Infisical confirmation code", recipients: [email], substitutions: { - code: token, - }, + code: token + } }); }; @@ -36,17 +36,11 @@ export const sendEmailVerification = async ({ email }: { email: string }) => { * @param {String} obj.email - emai * @param {String} obj.code - code that was sent to [email] */ -export const checkEmailVerification = async ({ - email, - code, -}: { - email: string; - code: string; -}) => { +export const checkEmailVerification = async ({ email, code }: { email: string; code: string }) => { await TokenService.validateToken({ type: TOKEN_EMAIL_CONFIRMATION, email, - token: code, + token: code }); }; @@ -58,27 +52,27 @@ export const checkEmailVerification = async ({ * @param {IUser} obj.user - user who we are initializing for */ export const initializeDefaultOrg = async ({ - organizationName, - user, + organizationName, + user }: { - organizationName: string; - user: IUser; + organizationName: string; + user: IUser; }) => { - try { - // create organization with user as owner and initialize a free - // subscription - const organization = await createOrganization({ - email: user.email, - name: organizationName, - }); + try { + // create organization with user as owner and initialize a free + // subscription + const organization = await createOrganization({ + email: user.email, + name: organizationName + }); - await addMembershipsOrg({ - userIds: [user._id.toString()], - organizationId: organization._id.toString(), - roles: [OWNER], - statuses: [ACCEPTED], - }); - } catch (err) { - throw new Error(`Failed to initialize default organization and workspace [err=${err}]`); - } -}; \ No newline at end of file + await addMembershipsOrg({ + userIds: [user._id.toString()], + organizationId: organization._id.toString(), + roles: [ADMIN], + statuses: [ACCEPTED] + }); + } catch (err) { + throw new Error(`Failed to initialize default organization and workspace [err=${err}]`); + } +}; diff --git a/backend/src/models/membershipOrg.ts b/backend/src/models/membershipOrg.ts index 530797379..09b16be84 100644 --- a/backend/src/models/membershipOrg.ts +++ b/backend/src/models/membershipOrg.ts @@ -1,5 +1,5 @@ import { Document, Schema, Types, model } from "mongoose"; -import { ACCEPTED, ADMIN, CUSTOM, INVITED, MEMBER, OWNER } from "../variables"; +import { ACCEPTED, ADMIN, CUSTOM, INVITED, MEMBER } from "../variables"; export interface IMembershipOrg extends Document { _id: Types.ObjectId; @@ -26,7 +26,7 @@ const membershipOrgSchema = new Schema( }, role: { type: String, - enum: [OWNER, ADMIN, MEMBER, CUSTOM], + enum: [ADMIN, MEMBER, CUSTOM], required: true }, status: { diff --git a/backend/src/queues/secret-scanning/githubScanFullRepository.ts b/backend/src/queues/secret-scanning/githubScanFullRepository.ts index 61d53acbb..eeb6aaf1e 100644 --- a/backend/src/queues/secret-scanning/githubScanFullRepository.ts +++ b/backend/src/queues/secret-scanning/githubScanFullRepository.ts @@ -4,7 +4,7 @@ import TelemetryService from "../../services/TelemetryService"; import { sendMail } from "../../helpers"; import GitRisks from "../../ee/models/gitRisks"; import { MembershipOrg, User } from "../../models"; -import { ADMIN, OWNER } from "../../variables"; +import { ADMIN } from "../../variables"; import { convertKeysToLowercase, scanFullRepoContentAndGetFindings } from "../../ee/services/GithubSecretScanning/helper"; import { getSecretScanningGitAppId, getSecretScanningPrivateKey } from "../../config"; import { SecretMatch } from "../../ee/services/GithubSecretScanning/types"; @@ -13,7 +13,7 @@ export const githubFullRepositorySecretScan = new Queue("github-full-repository- type TScanPushEventQueueDetails = { organizationId: string, - installationId: number, + installationId: number, repository: { id: number, fullName: string, @@ -24,22 +24,22 @@ githubFullRepositorySecretScan.process(async (job: Job, done: Queue.DoneCallback const { organizationId, repository, installationId }: TScanPushEventQueueDetails = job.data try { const octokit = new ProbotOctokit({ - auth: { + auth: { appId: await getSecretScanningGitAppId(), privateKey: await getSecretScanningPrivateKey(), installationId: installationId - }, + }, }); - const findings : SecretMatch[] = await scanFullRepoContentAndGetFindings(octokit, installationId, repository.fullName) + const findings: SecretMatch[] = await scanFullRepoContentAndGetFindings(octokit, installationId, repository.fullName) for (const finding of findings) { - await GitRisks.findOneAndUpdate({ fingerprint: finding.Fingerprint}, + await GitRisks.findOneAndUpdate({ fingerprint: finding.Fingerprint }, { - ...convertKeysToLowercase(finding), - installationId: installationId, - organization: organizationId, - repositoryFullName: repository.fullName, - repositoryId: repository.id - }, { + ...convertKeysToLowercase(finding), + installationId: installationId, + organization: organizationId, + repositoryFullName: repository.fullName, + repositoryId: repository.id + }, { upsert: true }).lean() } @@ -47,10 +47,7 @@ githubFullRepositorySecretScan.process(async (job: Job, done: Queue.DoneCallback // get emails of admins const adminsOfWork = await MembershipOrg.find({ organization: organizationId, - $or: [ - { role: OWNER }, - { role: ADMIN } - ] + role: ADMIN, }).lean() const userEmails = await User.find({ diff --git a/backend/src/queues/secret-scanning/githubScanPushEvent.ts b/backend/src/queues/secret-scanning/githubScanPushEvent.ts index 71a7e92d4..09261e235 100644 --- a/backend/src/queues/secret-scanning/githubScanPushEvent.ts +++ b/backend/src/queues/secret-scanning/githubScanPushEvent.ts @@ -5,7 +5,7 @@ import TelemetryService from "../../services/TelemetryService"; import { sendMail } from "../../helpers"; import GitRisks from "../../ee/models/gitRisks"; import { MembershipOrg, User } from "../../models"; -import { ADMIN, OWNER } from "../../variables"; +import { ADMIN } from "../../variables"; import { convertKeysToLowercase, scanContentAndGetFindings } from "../../ee/services/GithubSecretScanning/helper"; import { getSecretScanningGitAppId, getSecretScanningPrivateKey } from "../../config"; import { SecretMatch } from "../../ee/services/GithubSecretScanning/types"; @@ -88,10 +88,7 @@ githubPushEventSecretScan.process(async (job: Job, done: Queue.DoneCallback) => // get emails of admins const adminsOfWork = await MembershipOrg.find({ organization: organizationId, - $or: [ - { role: OWNER }, - { role: ADMIN } - ] + role: ADMIN }).lean() const userEmails = await User.find({ diff --git a/backend/src/routes/v2/organizations.ts b/backend/src/routes/v2/organizations.ts index a12288886..d1387bd42 100644 --- a/backend/src/routes/v2/organizations.ts +++ b/backend/src/routes/v2/organizations.ts @@ -4,7 +4,7 @@ import { requireAuth, requireOrganizationAuth } from "../../middleware"; -import { ACCEPTED, ADMIN, AuthMode, OWNER } from "../../variables"; +import { ACCEPTED, ADMIN, AuthMode } from "../../variables"; import { organizationsController } from "../../controllers/v2"; // TODO: /POST to create membership @@ -48,7 +48,7 @@ router.get( acceptedAuthModes: [AuthMode.JWT] }), requireOrganizationAuth({ - acceptedRoles: [OWNER, ADMIN], + acceptedRoles: [ADMIN], acceptedStatuses: [ACCEPTED] }), organizationsController.getOrganizationServiceAccounts diff --git a/backend/src/utils/setup/backfillData.ts b/backend/src/utils/setup/backfillData.ts index ae6279bfc..ccd38edcf 100644 --- a/backend/src/utils/setup/backfillData.ts +++ b/backend/src/utils/setup/backfillData.ts @@ -13,6 +13,7 @@ import { Integration, IntegrationAuth, Membership, + MembershipOrg, Organization, Secret, SecretBlindIndexData, @@ -23,12 +24,15 @@ import { import { generateKeyPair } from "../../utils/crypto"; import { client, getEncryptionKey, getRootEncryptionKey } from "../../config"; import { + ADMIN, ALGORITHM_AES_256_GCM, ENCODING_SCHEME_BASE64, ENCODING_SCHEME_UTF8, MEMBER, + OWNER, VIEWER } from "../../variables"; + import { InternalServerError } from "../errors"; /** @@ -691,5 +695,16 @@ export const backfillPermission = async () => { } ] ); + + await MembershipOrg.updateMany( + { + role: OWNER + }, + { + $set: { + role: ADMIN + } + } + ); console.log("Backfill: Finishing converting old denied permission in workspace to viewers"); }; diff --git a/backend/src/validation/secrets.ts b/backend/src/validation/secrets.ts index 700a3ea5d..cc541ab9e 100644 --- a/backend/src/validation/secrets.ts +++ b/backend/src/validation/secrets.ts @@ -225,8 +225,8 @@ export const GetSecretsV2 = z.object({ export const GetSecretsRawV3 = z.object({ query: z.object({ - workspaceId: z.string().trim(), - environment: z.string().trim(), + workspaceId: z.string().trim().optional(), + environment: z.string().trim().optional(), secretPath: z.string().trim().default("/"), folderId: z.string().trim().optional(), include_imports: z diff --git a/backend/src/variables/organization.ts b/backend/src/variables/organization.ts index bccabc6e6..5e796e357 100644 --- a/backend/src/variables/organization.ts +++ b/backend/src/variables/organization.ts @@ -1,5 +1,5 @@ // membership roles -export const OWNER = "owner"; +export const OWNER = "owner"; // depreciated export const ADMIN = "admin"; export const MEMBER = "member"; export const VIEWER = "viewer"; diff --git a/frontend/src/context/ProjectPermissionContext/ProjectPermissionContext.tsx b/frontend/src/context/ProjectPermissionContext/ProjectPermissionContext.tsx index 732466cf6..bb7fab7ec 100644 --- a/frontend/src/context/ProjectPermissionContext/ProjectPermissionContext.tsx +++ b/frontend/src/context/ProjectPermissionContext/ProjectPermissionContext.tsx @@ -16,14 +16,6 @@ export const ProjectPermissionProvider = ({ children }: Props): JSX.Element => { const workspaceId = currentWorkspace?._id || ""; const { data: permission, isLoading } = useGetUserProjectPermissions({ workspaceId }); - if (!permission && currentWorkspace) { - return ( -
- Failed to load user permissions -
- ); - } - if ((isLoading && currentWorkspace) || isWsLoading) { return (
@@ -37,6 +29,14 @@ export const ProjectPermissionProvider = ({ children }: Props): JSX.Element => { ); } + if (!permission && currentWorkspace) { + return ( +
+ Failed to load user permissions +
+ ); + } + return ( {children} diff --git a/frontend/src/layouts/AppLayout/AppLayout.tsx b/frontend/src/layouts/AppLayout/AppLayout.tsx index d03161f30..47f7570d8 100644 --- a/frontend/src/layouts/AppLayout/AppLayout.tsx +++ b/frontend/src/layouts/AppLayout/AppLayout.tsx @@ -138,7 +138,6 @@ export const AppLayout = ({ children }: LayoutProps) => { const { t } = useTranslation(); - const logout = useLogoutUser(); const logOutUser = async () => { try { @@ -488,7 +487,7 @@ export const AppLayout = ({ children }: LayoutProps) => { - + {/* { Audit Logs - - {/* - - - Audit Logs - - */} - {/* - - } - icon="system-outline-82-extension" - > - Audit Logs - - - */} { - if (isDeleteIntegrationAuthSuccess && !isIntegrationFetching && !integrations?.length) { + if ( + isDeleteIntegrationAuthSuccess && + !isIntegrationFetching && + !isIntegrationAuthLoading && + !integrations?.length && + !integrationAuths?.length + ) { if (bot?._id) updateBotActiveStatusSync({ isActive: false, @@ -94,7 +100,13 @@ export const IntegrationsPage = withProjectPermission( }); resetDeleteIntegrationAuth(); } - }, [isIntegrationFetching, isDeleteIntegrationAuthSuccess, integrations?.length]); + }, [ + isIntegrationFetching, + isDeleteIntegrationAuthSuccess, + isIntegrationAuthLoading, + integrationAuths?.length, + integrations?.length + ]); const handleProviderIntegration = async (provider: string) => { const selectedCloudIntegration = cloudIntegrations?.find(({ slug }) => provider === slug); diff --git a/frontend/src/views/Org/MembersPage/components/OrgRoleTabSection/OrgRoleModifySection/OrgRoleModifySection.tsx b/frontend/src/views/Org/MembersPage/components/OrgRoleTabSection/OrgRoleModifySection/OrgRoleModifySection.tsx index aa90c2fbf..4caeb4553 100644 --- a/frontend/src/views/Org/MembersPage/components/OrgRoleTabSection/OrgRoleModifySection/OrgRoleModifySection.tsx +++ b/frontend/src/views/Org/MembersPage/components/OrgRoleTabSection/OrgRoleModifySection/OrgRoleModifySection.tsx @@ -1,4 +1,3 @@ -import { useState } from "react"; import { useForm } from "react-hook-form"; import { faArrowLeft, @@ -80,7 +79,6 @@ const SIMPLE_PERMISSION_OPTIONS = [ ] as const; export const OrgRoleModifySection = ({ role, onGoBack }: Props) => { - const [searchPermission, setSearchPermission] = useState(""); const { subscription } = useSubscription(); const { popUp, handlePopUpToggle, handlePopUpOpen } = usePopUp(["upgradePlan"] as const); @@ -196,14 +194,6 @@ export const OrgRoleModifySection = ({ role, onGoBack }: Props) => {

Add Permission

-
- setSearchPermission(e.target.value)} - leftIcon={} - placeholder="Search permissions..." - /> -
{ title={t("section.members.add-dialog.add-member-to-project") as string} subTitle={t("section.members.add-dialog.user-will-email")} > -
- ( - - - - )} - /> -
- - + {filteredOrgUsers.length ? ( + + ( + + + + )} + /> +
+ + +
+ + ) : ( +
+
All the users in your organization are already invited.
+ + +
- + )} { - const [searchPermission, setSearchPermission] = useState(""); - const { popUp, handlePopUpToggle, handlePopUpOpen } = usePopUp(["upgradePlan"] as const); const isNonEditable = ["admin", "member", "viewer"].includes(role?.slug || ""); @@ -226,14 +215,6 @@ export const ProjectRoleModifySection = ({ role, onGoBack }: Props) => {

Add Permission

-
- setSearchPermission(e.target.value)} - leftIcon={} - placeholder="Search permissions..." - /> -
{ + switch (option) { + case "member": + return MEMBERS_PERMISSIONS; + default: + return PERMISSIONS; + } +}; + export const SingleProjectPermission = ({ isNonEditable, setValue, @@ -148,7 +164,7 @@ export const SingleProjectPermission = ({ className="overflow-hidden grid gap-8 grid-flow-col auto-cols-min" > {isCustom && - PERMISSIONS.map(({ action, label }) => ( + getPermissionList(formName).map(({ action, label }) => (