mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-05 22:26:41 +00:00
Patch for update org membership call, hide edit user on self user page
This commit is contained in:
@@ -57,7 +57,7 @@ type TOrgServiceFactoryDep = {
|
|||||||
projectDAL: TProjectDALFactory;
|
projectDAL: TProjectDALFactory;
|
||||||
projectMembershipDAL: Pick<TProjectMembershipDALFactory, "findProjectMembershipsByUserId" | "delete">;
|
projectMembershipDAL: Pick<TProjectMembershipDALFactory, "findProjectMembershipsByUserId" | "delete">;
|
||||||
projectKeyDAL: Pick<TProjectKeyDALFactory, "find" | "delete">;
|
projectKeyDAL: Pick<TProjectKeyDALFactory, "find" | "delete">;
|
||||||
orgMembershipDAL: Pick<TOrgMembershipDALFactory, "findOrgMembershipById">;
|
orgMembershipDAL: Pick<TOrgMembershipDALFactory, "findOrgMembershipById" | "findOne">;
|
||||||
incidentContactDAL: TIncidentContactsDALFactory;
|
incidentContactDAL: TIncidentContactsDALFactory;
|
||||||
samlConfigDAL: Pick<TSamlConfigDALFactory, "findOne" | "findEnforceableSamlCfg">;
|
samlConfigDAL: Pick<TSamlConfigDALFactory, "findOne" | "findEnforceableSamlCfg">;
|
||||||
smtpService: TSmtpService;
|
smtpService: TSmtpService;
|
||||||
@@ -379,7 +379,10 @@ export const orgServiceFactory = ({
|
|||||||
const { permission } = await permissionService.getUserOrgPermission(userId, orgId, actorAuthMethod, actorOrgId);
|
const { permission } = await permissionService.getUserOrgPermission(userId, orgId, actorAuthMethod, actorOrgId);
|
||||||
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Edit, OrgPermissionSubjects.Member);
|
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Edit, OrgPermissionSubjects.Member);
|
||||||
|
|
||||||
const [foundMembership] = await orgDAL.findMembership({ id: membershipId, orgId });
|
const foundMembership = await orgMembershipDAL.findOne({
|
||||||
|
id: membershipId,
|
||||||
|
orgId
|
||||||
|
});
|
||||||
if (!foundMembership) throw new NotFoundError({ message: "Failed to find organization membership" });
|
if (!foundMembership) throw new NotFoundError({ message: "Failed to find organization membership" });
|
||||||
if (foundMembership.userId === userId)
|
if (foundMembership.userId === userId)
|
||||||
throw new BadRequestError({ message: "Cannot update own organization membership" });
|
throw new BadRequestError({ message: "Cannot update own organization membership" });
|
||||||
|
|||||||
@@ -16,7 +16,12 @@ import {
|
|||||||
Tooltip,
|
Tooltip,
|
||||||
UpgradePlanModal
|
UpgradePlanModal
|
||||||
} from "@app/components/v2";
|
} from "@app/components/v2";
|
||||||
import { OrgPermissionActions, OrgPermissionSubjects, useOrganization } from "@app/context";
|
import {
|
||||||
|
OrgPermissionActions,
|
||||||
|
OrgPermissionSubjects,
|
||||||
|
useOrganization,
|
||||||
|
useUser
|
||||||
|
} from "@app/context";
|
||||||
import { withPermission } from "@app/hoc";
|
import { withPermission } from "@app/hoc";
|
||||||
import {
|
import {
|
||||||
useDeleteOrgMembership,
|
useDeleteOrgMembership,
|
||||||
@@ -31,7 +36,10 @@ export const UserPage = withPermission(
|
|||||||
() => {
|
() => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const membershipId = router.query.membershipId as string;
|
const membershipId = router.query.membershipId as string;
|
||||||
|
const { user } = useUser();
|
||||||
const { currentOrg } = useOrganization();
|
const { currentOrg } = useOrganization();
|
||||||
|
|
||||||
|
const userId = user?.id || "";
|
||||||
const orgId = currentOrg?.id || "";
|
const orgId = currentOrg?.id || "";
|
||||||
|
|
||||||
const { data: membership } = useGetOrgMembership(orgId, membershipId);
|
const { data: membership } = useGetOrgMembership(orgId, membershipId);
|
||||||
@@ -115,116 +123,118 @@ export const UserPage = withPermission(
|
|||||||
? `${membership.user.firstName} ${membership.user.lastName}`
|
? `${membership.user.firstName} ${membership.user.lastName}`
|
||||||
: "-"}
|
: "-"}
|
||||||
</p>
|
</p>
|
||||||
<DropdownMenu>
|
{userId !== membership.user.id && (
|
||||||
<DropdownMenuTrigger asChild className="rounded-lg">
|
<DropdownMenu>
|
||||||
<div className="hover:text-primary-400 data-[state=open]:text-primary-400">
|
<DropdownMenuTrigger asChild className="rounded-lg">
|
||||||
<Tooltip content="More options">
|
<div className="hover:text-primary-400 data-[state=open]:text-primary-400">
|
||||||
<FontAwesomeIcon size="sm" icon={faEllipsis} />
|
<Tooltip content="More options">
|
||||||
</Tooltip>
|
<FontAwesomeIcon size="sm" icon={faEllipsis} />
|
||||||
</div>
|
</Tooltip>
|
||||||
</DropdownMenuTrigger>
|
</div>
|
||||||
<DropdownMenuContent align="start" className="p-1">
|
</DropdownMenuTrigger>
|
||||||
<OrgPermissionCan
|
<DropdownMenuContent align="start" className="p-1">
|
||||||
I={OrgPermissionActions.Edit}
|
<OrgPermissionCan
|
||||||
a={OrgPermissionSubjects.Identity}
|
I={OrgPermissionActions.Edit}
|
||||||
>
|
a={OrgPermissionSubjects.Identity}
|
||||||
{(isAllowed) => (
|
>
|
||||||
<DropdownMenuItem
|
{(isAllowed) => (
|
||||||
className={twMerge(
|
<DropdownMenuItem
|
||||||
!isAllowed && "pointer-events-none cursor-not-allowed opacity-50"
|
className={twMerge(
|
||||||
)}
|
!isAllowed && "pointer-events-none cursor-not-allowed opacity-50"
|
||||||
onClick={() =>
|
)}
|
||||||
handlePopUpOpen("orgMembership", {
|
onClick={() =>
|
||||||
membershipId: membership.id,
|
handlePopUpOpen("orgMembership", {
|
||||||
role: membership.role
|
membershipId: membership.id,
|
||||||
})
|
role: membership.role
|
||||||
}
|
})
|
||||||
disabled={!isAllowed}
|
|
||||||
>
|
|
||||||
Edit User
|
|
||||||
</DropdownMenuItem>
|
|
||||||
)}
|
|
||||||
</OrgPermissionCan>
|
|
||||||
<OrgPermissionCan
|
|
||||||
I={OrgPermissionActions.Delete}
|
|
||||||
a={OrgPermissionSubjects.Member}
|
|
||||||
>
|
|
||||||
{(isAllowed) => (
|
|
||||||
<DropdownMenuItem
|
|
||||||
className={
|
|
||||||
membership.isActive
|
|
||||||
? twMerge(
|
|
||||||
isAllowed
|
|
||||||
? "hover:!bg-red-500 hover:!text-white"
|
|
||||||
: "pointer-events-none cursor-not-allowed opacity-50"
|
|
||||||
)
|
|
||||||
: ""
|
|
||||||
}
|
|
||||||
onClick={async () => {
|
|
||||||
if (currentOrg?.scimEnabled) {
|
|
||||||
createNotification({
|
|
||||||
text: "You cannot manage users from Infisical when SCIM is enabled for your organization",
|
|
||||||
type: "error"
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
disabled={!isAllowed}
|
||||||
if (!membership.isActive) {
|
>
|
||||||
// activate user
|
Edit User
|
||||||
await updateOrgMembership({
|
</DropdownMenuItem>
|
||||||
organizationId: orgId,
|
)}
|
||||||
membershipId,
|
</OrgPermissionCan>
|
||||||
isActive: true
|
<OrgPermissionCan
|
||||||
});
|
I={OrgPermissionActions.Delete}
|
||||||
|
a={OrgPermissionSubjects.Member}
|
||||||
return;
|
>
|
||||||
|
{(isAllowed) => (
|
||||||
|
<DropdownMenuItem
|
||||||
|
className={
|
||||||
|
membership.isActive
|
||||||
|
? twMerge(
|
||||||
|
isAllowed
|
||||||
|
? "hover:!bg-red-500 hover:!text-white"
|
||||||
|
: "pointer-events-none cursor-not-allowed opacity-50"
|
||||||
|
)
|
||||||
|
: ""
|
||||||
}
|
}
|
||||||
|
onClick={async () => {
|
||||||
|
if (currentOrg?.scimEnabled) {
|
||||||
|
createNotification({
|
||||||
|
text: "You cannot manage users from Infisical when SCIM is enabled for your organization",
|
||||||
|
type: "error"
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// deactivate user
|
if (!membership.isActive) {
|
||||||
handlePopUpOpen("deactivateMember", {
|
// activate user
|
||||||
orgMembershipId: membershipId,
|
await updateOrgMembership({
|
||||||
username: membership.user.username
|
organizationId: orgId,
|
||||||
});
|
membershipId,
|
||||||
}}
|
isActive: true
|
||||||
disabled={!isAllowed}
|
});
|
||||||
>
|
|
||||||
{`${membership.isActive ? "Deactivate" : "Activate"} User`}
|
return;
|
||||||
</DropdownMenuItem>
|
}
|
||||||
)}
|
|
||||||
</OrgPermissionCan>
|
// deactivate user
|
||||||
<OrgPermissionCan
|
handlePopUpOpen("deactivateMember", {
|
||||||
I={OrgPermissionActions.Delete}
|
orgMembershipId: membershipId,
|
||||||
a={OrgPermissionSubjects.Member}
|
username: membership.user.username
|
||||||
>
|
|
||||||
{(isAllowed) => (
|
|
||||||
<DropdownMenuItem
|
|
||||||
className={twMerge(
|
|
||||||
isAllowed
|
|
||||||
? "hover:!bg-red-500 hover:!text-white"
|
|
||||||
: "pointer-events-none cursor-not-allowed opacity-50"
|
|
||||||
)}
|
|
||||||
onClick={() => {
|
|
||||||
if (currentOrg?.scimEnabled) {
|
|
||||||
createNotification({
|
|
||||||
text: "You cannot manage users from Infisical when SCIM is enabled for your organization",
|
|
||||||
type: "error"
|
|
||||||
});
|
});
|
||||||
return;
|
}}
|
||||||
}
|
disabled={!isAllowed}
|
||||||
|
>
|
||||||
|
{`${membership.isActive ? "Deactivate" : "Activate"} User`}
|
||||||
|
</DropdownMenuItem>
|
||||||
|
)}
|
||||||
|
</OrgPermissionCan>
|
||||||
|
<OrgPermissionCan
|
||||||
|
I={OrgPermissionActions.Delete}
|
||||||
|
a={OrgPermissionSubjects.Member}
|
||||||
|
>
|
||||||
|
{(isAllowed) => (
|
||||||
|
<DropdownMenuItem
|
||||||
|
className={twMerge(
|
||||||
|
isAllowed
|
||||||
|
? "hover:!bg-red-500 hover:!text-white"
|
||||||
|
: "pointer-events-none cursor-not-allowed opacity-50"
|
||||||
|
)}
|
||||||
|
onClick={() => {
|
||||||
|
if (currentOrg?.scimEnabled) {
|
||||||
|
createNotification({
|
||||||
|
text: "You cannot manage users from Infisical when SCIM is enabled for your organization",
|
||||||
|
type: "error"
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
handlePopUpOpen("removeMember", {
|
handlePopUpOpen("removeMember", {
|
||||||
orgMembershipId: membershipId,
|
orgMembershipId: membershipId,
|
||||||
username: membership.user.username
|
username: membership.user.username
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
disabled={!isAllowed}
|
disabled={!isAllowed}
|
||||||
>
|
>
|
||||||
Remove User
|
Remove User
|
||||||
</DropdownMenuItem>
|
</DropdownMenuItem>
|
||||||
)}
|
)}
|
||||||
</OrgPermissionCan>
|
</OrgPermissionCan>
|
||||||
</DropdownMenuContent>
|
</DropdownMenuContent>
|
||||||
</DropdownMenu>
|
</DropdownMenu>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className="flex">
|
<div className="flex">
|
||||||
<div className="mr-4 w-96">
|
<div className="mr-4 w-96">
|
||||||
|
|||||||
+2
-2
@@ -3,7 +3,7 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
|||||||
|
|
||||||
import { createNotification } from "@app/components/notifications";
|
import { createNotification } from "@app/components/notifications";
|
||||||
import { DeleteActionModal, IconButton } from "@app/components/v2";
|
import { DeleteActionModal, IconButton } from "@app/components/v2";
|
||||||
import { useOrganization,useUser } from "@app/context";
|
import { useOrganization, useUser } from "@app/context";
|
||||||
import { useDeleteUserFromWorkspace, useGetOrgMembership } from "@app/hooks/api";
|
import { useDeleteUserFromWorkspace, useGetOrgMembership } from "@app/hooks/api";
|
||||||
import { usePopUp } from "@app/hooks/usePopUp";
|
import { usePopUp } from "@app/hooks/usePopUp";
|
||||||
|
|
||||||
@@ -51,7 +51,7 @@ export const UserProjectsSection = ({ membershipId }: Props) => {
|
|||||||
<div className="w-full rounded-lg border border-mineshaft-600 bg-mineshaft-900 p-4">
|
<div className="w-full rounded-lg border border-mineshaft-600 bg-mineshaft-900 p-4">
|
||||||
<div className="flex items-center justify-between border-b border-mineshaft-400 pb-4">
|
<div className="flex items-center justify-between border-b border-mineshaft-400 pb-4">
|
||||||
<h3 className="text-lg font-semibold text-mineshaft-100">Projects</h3>
|
<h3 className="text-lg font-semibold text-mineshaft-100">Projects</h3>
|
||||||
{userId !== membership.user.id && (
|
{userId !== membership.user.id && Boolean(membership.user.publicKey) && (
|
||||||
<IconButton
|
<IconButton
|
||||||
ariaLabel="copy icon"
|
ariaLabel="copy icon"
|
||||||
variant="plain"
|
variant="plain"
|
||||||
|
|||||||
Reference in New Issue
Block a user