mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-09-22 13:39:35 +00:00
feat: more ui improvements
This commit is contained in:
@@ -230,7 +230,7 @@ export const identityV2ServiceFactory = ({
|
||||
const { scopeData } = dto;
|
||||
const factory = scopeFactory[scopeData.scope];
|
||||
|
||||
await factory.onListIdentityGuard(dto);
|
||||
const isIdentityAccessible = await factory.onListIdentityGuard(dto);
|
||||
|
||||
const identities = await identityDAL.listIdentities(dto.scopeData, {
|
||||
search: dto.data.search,
|
||||
@@ -238,7 +238,7 @@ export const identityV2ServiceFactory = ({
|
||||
limit: dto.data.limit
|
||||
});
|
||||
|
||||
return identities;
|
||||
return { ...identities, docs: identities.docs.filter((el) => isIdentityAccessible({ identityId: el.id })) };
|
||||
};
|
||||
|
||||
return {
|
||||
|
||||
@@ -5,7 +5,7 @@ export interface TIdentityV2Factory {
|
||||
onCreateIdentityGuard: (arg: TCreateIdentityV2DTO) => Promise<void>;
|
||||
onUpdateIdentityGuard: (arg: TUpdateIdentityV2DTO) => Promise<void>;
|
||||
onDeleteIdentityGuard: (arg: TDeleteIdentityV2DTO) => Promise<void>;
|
||||
onListIdentityGuard: (arg: TListIdentityV2DTO) => Promise<void>;
|
||||
onListIdentityGuard: (arg: TListIdentityV2DTO) => Promise<(arg: { identityId: string }) => boolean>;
|
||||
onGetIdentityByIdGuard: (arg: TGetIdentityByIdV2DTO) => Promise<void>;
|
||||
getScopeField: (scope: AccessScopeData) => { key: "orgId" | "namespaceId" | "projectId"; value: string };
|
||||
}
|
||||
|
||||
@@ -65,6 +65,8 @@ export const newOrgIdentityFactory = ({ permissionService }: TOrgIdentityFactory
|
||||
scope: OrganizationActionScope.Any
|
||||
});
|
||||
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Read, OrgPermissionSubjects.Identity);
|
||||
|
||||
return () => true;
|
||||
};
|
||||
|
||||
const onGetIdentityByIdGuard: TIdentityV2Factory["onGetIdentityByIdGuard"] = async (dto) => {
|
||||
|
||||
@@ -81,6 +81,12 @@ export const newProjectIdentityFactory = ({ permissionService }: TProjectIdentit
|
||||
ProjectPermissionIdentityActions.Read,
|
||||
ProjectPermissionSub.Identity
|
||||
);
|
||||
|
||||
return (arg) =>
|
||||
permission.can(
|
||||
ProjectPermissionIdentityActions.Read,
|
||||
subject(ProjectPermissionSub.Identity, { identityId: arg.identityId })
|
||||
);
|
||||
};
|
||||
|
||||
const onGetIdentityByIdGuard: TIdentityV2Factory["onGetIdentityByIdGuard"] = async (dto) => {
|
||||
|
||||
@@ -6,7 +6,7 @@ export interface TMembershipIdentityScopeFactory {
|
||||
|
||||
onUpdateMembershipIdentityGuard: (arg: TUpdateMembershipIdentityDTO) => Promise<void>;
|
||||
onDeleteMembershipIdentityGuard: (arg: TDeleteMembershipIdentityDTO) => Promise<void>;
|
||||
onListMembershipIdentityGuard: (arg: TListMembershipIdentityDTO) => Promise<void>;
|
||||
onListMembershipIdentityGuard: (arg: TListMembershipIdentityDTO) => Promise<(arg: { identityId: string }) => boolean>;
|
||||
onGetMembershipIdentityByIdentityIdGuard: (arg: TGetMembershipIdentityByIdentityIdDTO) => Promise<void>;
|
||||
getScopeField: (scope: AccessScopeData) => { key: "orgId" | "namespaceId" | "projectId"; value: string };
|
||||
getScopeDatabaseFields: (scope: AccessScopeData) => {
|
||||
|
||||
@@ -180,6 +180,8 @@ export const newOrgMembershipIdentityFactory = ({
|
||||
scope: OrganizationActionScope.Any
|
||||
});
|
||||
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Read, OrgPermissionSubjects.Identity);
|
||||
|
||||
return () => true;
|
||||
};
|
||||
|
||||
const onGetMembershipIdentityByIdentityIdGuard: TMembershipIdentityScopeFactory["onGetMembershipIdentityByIdentityIdGuard"] =
|
||||
|
||||
@@ -194,6 +194,12 @@ export const newProjectMembershipIdentityFactory = ({
|
||||
ProjectPermissionIdentityActions.Read,
|
||||
ProjectPermissionSub.Identity
|
||||
);
|
||||
|
||||
return (arg) =>
|
||||
permission.can(
|
||||
ProjectPermissionIdentityActions.Read,
|
||||
subject(ProjectPermissionSub.Identity, { identityId: arg.identityId })
|
||||
);
|
||||
};
|
||||
|
||||
const onGetMembershipIdentityByIdentityIdGuard: TMembershipIdentityScopeFactory["onGetMembershipIdentityByIdentityIdGuard"] =
|
||||
|
||||
@@ -423,7 +423,9 @@ export const IdentityTable = ({ handlePopUpOpen }: Props) => {
|
||||
isDisabled={!isAllowed}
|
||||
icon={<FontAwesomeIcon icon={faTrash} />}
|
||||
>
|
||||
Delete Identity
|
||||
{orgId !== currentOrg.id
|
||||
? "Remove From Sub-organization"
|
||||
: "Delete Identity"}
|
||||
</DropdownMenuItem>
|
||||
)}
|
||||
</OrgPermissionCan>
|
||||
|
||||
@@ -7,9 +7,14 @@ import { Link, useNavigate, useParams } from "@tanstack/react-router";
|
||||
import { UpgradePlanModal } from "@app/components/license/UpgradePlanModal";
|
||||
import { createNotification } from "@app/components/notifications";
|
||||
import { OrgPermissionCan } from "@app/components/permissions";
|
||||
import { DeleteActionModal, Modal, ModalContent, PageHeader } from "@app/components/v2";
|
||||
import { Button, DeleteActionModal, Modal, ModalContent, PageHeader } from "@app/components/v2";
|
||||
import { ROUTE_PATHS } from "@app/const/routes";
|
||||
import { OrgPermissionIdentityActions, OrgPermissionSubjects, useOrganization } from "@app/context";
|
||||
import {
|
||||
OrgPermissionActions,
|
||||
OrgPermissionIdentityActions,
|
||||
OrgPermissionSubjects,
|
||||
useOrganization
|
||||
} from "@app/context";
|
||||
import { useDeleteOrgIdentity, useGetOrgIdentityMembershipById } from "@app/hooks/api";
|
||||
import { usePopUp } from "@app/hooks/usePopUp";
|
||||
import { ViewIdentityAuthModal } from "@app/pages/organization/IdentityDetailsByIDPage/components/ViewIdentityAuthModal/ViewIdentityAuthModal";
|
||||
@@ -32,7 +37,7 @@ const Page = () => {
|
||||
const { currentOrg, isSubOrganization } = useOrganization();
|
||||
const orgId = currentOrg?.id || "";
|
||||
const { data } = useGetOrgIdentityMembershipById(identityId);
|
||||
const { mutateAsync: deleteIdentity } = useDeleteOrgIdentity();
|
||||
const { mutateAsync: deleteIdentity, isPending: isDeletingIdentity } = useDeleteOrgIdentity();
|
||||
const isAuthHidden = orgId !== data?.identity?.orgId;
|
||||
|
||||
const { popUp, handlePopUpOpen, handlePopUpClose, handlePopUpToggle } = usePopUp([
|
||||
@@ -81,7 +86,36 @@ const Page = () => {
|
||||
scope={isSubOrganization ? "namespace" : "org"}
|
||||
description={`${isSubOrganization ? "Sub-" : ""}Organization Identity`}
|
||||
title={data.identity.name}
|
||||
/>
|
||||
>
|
||||
<div className="flex items-center gap-2">
|
||||
{isSubOrganization && data.identity.orgId !== currentOrg.id && (
|
||||
<OrgPermissionCan
|
||||
I={OrgPermissionActions.Delete}
|
||||
a={OrgPermissionSubjects.Identity}
|
||||
renderTooltip
|
||||
allowedLabel="Remove from sub-organization"
|
||||
>
|
||||
{(isAllowed) => (
|
||||
<Button
|
||||
colorSchema="danger"
|
||||
variant="outline_bg"
|
||||
size="xs"
|
||||
isDisabled={!isAllowed}
|
||||
isLoading={isDeletingIdentity}
|
||||
onClick={() =>
|
||||
handlePopUpOpen("deleteIdentity", {
|
||||
identityId: data.identity.id,
|
||||
name: data.identity.name
|
||||
})
|
||||
}
|
||||
>
|
||||
Unlink Identity
|
||||
</Button>
|
||||
)}
|
||||
</OrgPermissionCan>
|
||||
)}
|
||||
</div>
|
||||
</PageHeader>
|
||||
<div className="flex">
|
||||
<div className="mr-4 w-96">
|
||||
<IdentityDetailsSection
|
||||
|
||||
@@ -86,7 +86,7 @@ export const IdentityDetailsSection = ({ identityId, handlePopUpOpen, isOrgIdent
|
||||
}}
|
||||
disabled={!isAllowed}
|
||||
>
|
||||
Edit Identity
|
||||
{isOrgIdentity ? "Edit Identity" : "Edit Identity Role"}
|
||||
</DropdownMenuItem>
|
||||
)}
|
||||
</OrgPermissionCan>
|
||||
@@ -110,7 +110,7 @@ export const IdentityDetailsSection = ({ identityId, handlePopUpOpen, isOrgIdent
|
||||
icon={<FontAwesomeIcon icon={faTrash} />}
|
||||
disabled={!isAllowed}
|
||||
>
|
||||
Delete Identity
|
||||
{!isOrgIdentity ? "Unlink Identity" : "Delete Identity"}
|
||||
</DropdownMenuItem>
|
||||
)}
|
||||
</OrgPermissionCan>
|
||||
|
||||
Reference in New Issue
Block a user