mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-09-22 13:39:35 +00:00
feat: updated frontend with the new endpoints for project identity
memberships
This commit is contained in:
@@ -7,13 +7,13 @@ import {
|
||||
ProjectMembershipRole,
|
||||
TemporaryPermissionMode
|
||||
} from "@app/db/schemas";
|
||||
import { EventType } from "@app/ee/services/audit-log/audit-log-types";
|
||||
import { ApiDocsTags, PROJECT_IDENTITIES, PROJECT_IDENTITY_MEMBERSHIP } from "@app/lib/api-docs";
|
||||
import { BadRequestError } from "@app/lib/errors";
|
||||
import { ms } from "@app/lib/ms";
|
||||
import { readLimit, writeLimit } from "@app/server/config/rateLimiter";
|
||||
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
|
||||
import { AuthMode } from "@app/services/auth/auth-type";
|
||||
import { EventType } from "@app/ee/services/audit-log/audit-log-types";
|
||||
|
||||
export const registerIdentityProjectMembershipRouter = async (server: FastifyZodProvider) => {
|
||||
server.route({
|
||||
@@ -289,7 +289,7 @@ export const registerIdentityProjectMembershipRouter = async (server: FastifyZod
|
||||
limit: z.coerce
|
||||
.number()
|
||||
.min(1)
|
||||
.max(100)
|
||||
.max(1000)
|
||||
.default(20)
|
||||
.describe(PROJECT_IDENTITY_MEMBERSHIP.LIST_IDENTITY_MEMBERSHIPS.limit)
|
||||
.optional(),
|
||||
@@ -456,7 +456,7 @@ export const registerIdentityProjectMembershipRouter = async (server: FastifyZod
|
||||
limit: z.coerce
|
||||
.number()
|
||||
.min(1)
|
||||
.max(100)
|
||||
.max(1000)
|
||||
.default(20)
|
||||
.describe(PROJECT_IDENTITY_MEMBERSHIP.LIST_AVAILABLE_IDENTITIES.limit)
|
||||
.optional(),
|
||||
|
||||
@@ -14,6 +14,7 @@ import { CERTIFICATE_AUTHORITY_REGISTER_ROUTER_MAP } from "./certificate-authori
|
||||
import { registerCertificateProfilesRouter } from "./certificate-profiles-router";
|
||||
import { registerCertRouter } from "./certificate-router";
|
||||
import { registerCertificateTemplateRouter } from "./certificate-template-router";
|
||||
import { registerDeprecatedIdentityProjectMembershipRouter } from "./deprecated-identity-project-membership-router";
|
||||
import { registerDeprecatedProjectEnvRouter } from "./deprecated-project-env-router";
|
||||
import { registerDeprecatedProjectMembershipRouter } from "./deprecated-project-membership-router";
|
||||
import { registerDeprecatedProjectRouter } from "./deprecated-project-router";
|
||||
@@ -34,7 +35,7 @@ import { registerIdentityLdapAuthRouter } from "./identity-ldap-auth-router";
|
||||
import { registerIdentityOciAuthRouter } from "./identity-oci-auth-router";
|
||||
import { registerIdentityOidcAuthRouter } from "./identity-oidc-auth-router";
|
||||
import { registerIdentityOrgMembershipRouter } from "./identity-org-membership-router";
|
||||
import { registerDeprecatedIdentityProjectMembershipRouter } from "./deprecated-identity-project-membership-router";
|
||||
import { registerIdentityProjectMembershipRouter } from "./identity-project-membership-router";
|
||||
import { registerIdentityRouter } from "./identity-router";
|
||||
import { registerIdentityTlsCertAuthRouter } from "./identity-tls-cert-auth-router";
|
||||
import { registerIdentityTokenAuthRouter } from "./identity-token-auth-router";
|
||||
@@ -69,7 +70,6 @@ import { registerUserEngagementRouter } from "./user-engagement-router";
|
||||
import { registerUserRouter } from "./user-router";
|
||||
import { registerWebhookRouter } from "./webhook-router";
|
||||
import { registerWorkflowIntegrationRouter } from "./workflow-integration-router";
|
||||
import { registerIdentityProjectMembershipRouter } from "./identity-project-membership-router";
|
||||
|
||||
export const registerV1Routes = async (server: FastifyZodProvider) => {
|
||||
await server.register(registerSsoRouter, { prefix: "/sso" });
|
||||
|
||||
@@ -16,7 +16,7 @@ import {
|
||||
IdentityMembershipOrg,
|
||||
IdentityOciAuth,
|
||||
IdentityOidcAuth,
|
||||
IdentityProjectMembership,
|
||||
IdentityProjectMembershipV1,
|
||||
IdentityTlsCertAuth,
|
||||
IdentityTokenAuth,
|
||||
IdentityUniversalAuth,
|
||||
@@ -95,7 +95,7 @@ export const useGetIdentityProjectMemberships = (identityId: string) => {
|
||||
queryFn: async () => {
|
||||
const {
|
||||
data: { identityMemberships }
|
||||
} = await apiRequest.get<{ identityMemberships: IdentityProjectMembership[] }>(
|
||||
} = await apiRequest.get<{ identityMemberships: IdentityProjectMembershipV1[] }>(
|
||||
`/api/v1/identities/${identityId}/identity-memberships`
|
||||
);
|
||||
return identityMemberships;
|
||||
|
||||
@@ -56,7 +56,7 @@ export type IdentityMembershipOrg = {
|
||||
updatedAt: string;
|
||||
};
|
||||
|
||||
export type IdentityProjectMembership = {
|
||||
export type IdentityProjectMembershipV1 = {
|
||||
id: string;
|
||||
identity: Identity;
|
||||
project: Pick<Project, "id" | "name" | "type">;
|
||||
@@ -90,6 +90,39 @@ export type IdentityProjectMembership = {
|
||||
lastLoginAuthMethod?: IdentityAuthMethod;
|
||||
};
|
||||
|
||||
export type IdentityProjectMembershipV2 = {
|
||||
id: string;
|
||||
identity: Identity;
|
||||
roles: Array<
|
||||
{
|
||||
id: string;
|
||||
role: "owner" | "admin" | "member" | "no-access" | "custom";
|
||||
customRoleId: string;
|
||||
customRoleName: string;
|
||||
customRoleSlug: string;
|
||||
} & (
|
||||
| {
|
||||
isTemporary: false;
|
||||
temporaryRange: null;
|
||||
temporaryMode: null;
|
||||
temporaryAccessEndTime: null;
|
||||
temporaryAccessStartTime: null;
|
||||
}
|
||||
| {
|
||||
isTemporary: true;
|
||||
temporaryRange: string;
|
||||
temporaryMode: TemporaryPermissionMode;
|
||||
temporaryAccessEndTime: string;
|
||||
temporaryAccessStartTime: string;
|
||||
}
|
||||
)
|
||||
>;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
lastLoginTime?: string;
|
||||
lastLoginAuthMethod?: IdentityAuthMethod;
|
||||
};
|
||||
|
||||
export type CreateIdentityDTO = {
|
||||
name: string;
|
||||
organizationId: string;
|
||||
@@ -828,7 +861,12 @@ export type RevokeTokenRes = {
|
||||
};
|
||||
|
||||
export type TProjectIdentityMembershipsList = {
|
||||
identityMemberships: IdentityProjectMembership[];
|
||||
identityMemberships: IdentityProjectMembershipV1[];
|
||||
totalCount: number;
|
||||
};
|
||||
|
||||
export type TProjectIdentityMembershipsListV2 = {
|
||||
identityMemberships: IdentityProjectMembershipV2[];
|
||||
totalCount: number;
|
||||
};
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ export const useCreateProjectIdentityMembership = () => {
|
||||
const {
|
||||
data: { identityMembership }
|
||||
} = await apiRequest.post<{ identityMembership: TProjectIdentityMembership }>(
|
||||
`/api/v1/projects/${projectId}/identity-memberships/${identityId}`,
|
||||
`/api/v1/projects/${projectId}/memberships/identities/${identityId}`,
|
||||
{
|
||||
role
|
||||
}
|
||||
@@ -49,7 +49,7 @@ export const useUpdateProjectIdentityMembership = () => {
|
||||
const {
|
||||
data: { identityMembership }
|
||||
} = await apiRequest.patch<{ identityMembership: TProjectIdentityMembership }>(
|
||||
`/api/v1/projects/${projectId}/identity-memberships/${identityId}`,
|
||||
`/api/v1/projects/${projectId}/memberships/identities/${identityId}`,
|
||||
updates
|
||||
);
|
||||
return identityMembership;
|
||||
@@ -76,7 +76,7 @@ export const useDeleteProjectIdentityMembership = () => {
|
||||
const {
|
||||
data: { identityMembership }
|
||||
} = await apiRequest.delete<{ identityMembership: TProjectIdentityMembership }>(
|
||||
`/api/v1/projects/${projectId}/identity-memberships/${identityId}`
|
||||
`/api/v1/projects/${projectId}/memberships/identities/${identityId}`
|
||||
);
|
||||
return identityMembership;
|
||||
},
|
||||
|
||||
@@ -8,8 +8,8 @@ import {
|
||||
} from "@app/hooks/api";
|
||||
import { OrderByDirection } from "@app/hooks/api/generic/types";
|
||||
import {
|
||||
IdentityProjectMembership,
|
||||
TProjectIdentityMembershipsList
|
||||
IdentityProjectMembershipV1,
|
||||
TProjectIdentityMembershipsListV2
|
||||
} from "@app/hooks/api/identities/types";
|
||||
import { ProjectIdentityOrderBy, TListProjectIdentitiesDTO } from "@app/hooks/api/projects/types";
|
||||
|
||||
@@ -23,7 +23,7 @@ export const projectIdentityMembershipQuery = {
|
||||
queryFn: async () => {
|
||||
const { data } = await apiRequest.get<{
|
||||
identities: TAvailableProjectIdentities;
|
||||
}>(`/api/v1/projects/${params.projectId}/available-identities`, {
|
||||
}>(`/api/v1/projects/${params.projectId}/memberships/available-identities`, {
|
||||
params: {
|
||||
offset: params.offset,
|
||||
limit: params.limit,
|
||||
@@ -48,9 +48,9 @@ export const useListProjectIdentityMemberships = (
|
||||
}: TListProjectIdentitiesDTO,
|
||||
options?: Omit<
|
||||
UseQueryOptions<
|
||||
TProjectIdentityMembershipsList,
|
||||
TProjectIdentityMembershipsListV2,
|
||||
unknown,
|
||||
TProjectIdentityMembershipsList,
|
||||
TProjectIdentityMembershipsListV2,
|
||||
ReturnType<typeof projectKeys.getProjectIdentityMembershipsWithParams>
|
||||
>,
|
||||
"queryKey" | "queryFn"
|
||||
@@ -74,8 +74,8 @@ export const useListProjectIdentityMemberships = (
|
||||
search: String(search)
|
||||
});
|
||||
|
||||
const { data } = await apiRequest.get<TProjectIdentityMembershipsList>(
|
||||
`/api/v1/projects/${projectId}/identity-memberships`,
|
||||
const { data } = await apiRequest.get<TProjectIdentityMembershipsListV2>(
|
||||
`/api/v1/projects/${projectId}/memberships/identities`,
|
||||
{ params }
|
||||
);
|
||||
return data;
|
||||
@@ -92,7 +92,7 @@ export const useGetProjectIdentityMembership = (projectId: string, identityId: s
|
||||
queryFn: async () => {
|
||||
const {
|
||||
data: { identityMembership }
|
||||
} = await apiRequest.get<{ identityMembership: IdentityProjectMembership }>(
|
||||
} = await apiRequest.get<{ identityMembership: IdentityProjectMembershipV1 }>(
|
||||
`/api/v1/projects/${projectId}/identity-memberships/${identityId}`
|
||||
);
|
||||
return identityMembership;
|
||||
@@ -107,8 +107,8 @@ export const useGetProjectIdentityMembershipV2 = (projectId: string, identityId:
|
||||
queryFn: async () => {
|
||||
const {
|
||||
data: { identityMembership }
|
||||
} = await apiRequest.get<{ identityMembership: IdentityProjectMembership }>(
|
||||
`/api/v2/projects/${projectId}/identity-memberships/${identityId}`
|
||||
} = await apiRequest.get<{ identityMembership: IdentityProjectMembershipV1 }>(
|
||||
`/api/v1/projects/${projectId}/memberships/identities/${identityId}`
|
||||
);
|
||||
return identityMembership;
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ import { IconButton, Td, Tooltip, Tr } from "@app/components/v2";
|
||||
import { getProjectBaseURL } from "@app/helpers/project";
|
||||
import { formatProjectRoleName } from "@app/helpers/roles";
|
||||
import { useGetUserProjects } from "@app/hooks/api";
|
||||
import { IdentityProjectMembership } from "@app/hooks/api/identities/types";
|
||||
import { IdentityProjectMembershipV1 } from "@app/hooks/api/identities/types";
|
||||
import { UsePopUpState } from "@app/hooks/usePopUp";
|
||||
|
||||
export enum TabSections {
|
||||
@@ -20,7 +20,7 @@ export enum TabSections {
|
||||
}
|
||||
|
||||
type Props = {
|
||||
membership: IdentityProjectMembership;
|
||||
membership: IdentityProjectMembershipV1;
|
||||
handlePopUpOpen: (
|
||||
popUpName: keyof UsePopUpState<["removeIdentityFromProject"]>,
|
||||
data?: object
|
||||
|
||||
@@ -47,7 +47,7 @@ export const ProjectLinkIdentityModal = ({ handlePopUpToggle }: Props) => {
|
||||
|
||||
const { data: identityMembershipsData } = useListProjectIdentityMemberships({
|
||||
projectId,
|
||||
limit: 20000 // TODO: this is temp to preserve functionality for larger projects, will optimize in PR referenced above
|
||||
limit: 1000 // TODO: this is temp to preserve functionality for larger projects, will optimize in PR referenced above
|
||||
});
|
||||
const identityMemberships = identityMembershipsData?.identityMemberships;
|
||||
|
||||
|
||||
@@ -10,6 +10,8 @@ import { formatRelative } from "date-fns";
|
||||
import { createNotification } from "@app/components/notifications";
|
||||
import { ProjectPermissionCan } from "@app/components/permissions";
|
||||
import {
|
||||
Alert,
|
||||
AlertDescription,
|
||||
Button,
|
||||
ConfirmActionModal,
|
||||
DeleteActionModal,
|
||||
@@ -147,6 +149,7 @@ const Page = () => {
|
||||
scope={currentProject.type}
|
||||
title={identityMembershipDetails?.identity?.name}
|
||||
description={`Identity ${isProjectIdentity ? "created" : "added"} on ${identityMembershipDetails?.createdAt && formatRelative(new Date(identityMembershipDetails?.createdAt || ""), new Date())}`}
|
||||
className={!isProjectIdentity ? "mb-4" : undefined}
|
||||
>
|
||||
<div className="flex items-center gap-2">
|
||||
<Button
|
||||
@@ -207,6 +210,23 @@ const Page = () => {
|
||||
)}
|
||||
</div>
|
||||
</PageHeader>
|
||||
{!isProjectIdentity && (
|
||||
<Alert hideTitle className="mb-4 border-primary/50 bg-primary/10">
|
||||
<AlertDescription>
|
||||
This identity is managed by your organization.{" "}
|
||||
<Link
|
||||
to="/organization/identities/$identityId"
|
||||
params={{
|
||||
identityId
|
||||
}}
|
||||
>
|
||||
<span className="cursor-pointer text-primary underline underline-offset-2">
|
||||
Click here to retrieve credentials.
|
||||
</span>
|
||||
</Link>
|
||||
</AlertDescription>
|
||||
</Alert>
|
||||
)}
|
||||
<div className="flex gap-x-4">
|
||||
{identity ? (
|
||||
<div className="flex w-72 flex-col gap-y-4">
|
||||
|
||||
@@ -31,13 +31,13 @@ import {
|
||||
} from "@app/context";
|
||||
import { usePopUp } from "@app/hooks";
|
||||
import { useDeleteIdentityProjectAdditionalPrivilege } from "@app/hooks/api";
|
||||
import { IdentityProjectMembership } from "@app/hooks/api/identities/types";
|
||||
import { IdentityProjectMembershipV1 } from "@app/hooks/api/identities/types";
|
||||
import { useListIdentityProjectPrivileges } from "@app/hooks/api/identityProjectAdditionalPrivilege/queries";
|
||||
|
||||
import { IdentityProjectAdditionalPrivilegeModifySection } from "./IdentityProjectAdditionalPrivilegeModifySection";
|
||||
|
||||
type Props = {
|
||||
identityMembershipDetails: IdentityProjectMembership;
|
||||
identityMembershipDetails: IdentityProjectMembershipV1;
|
||||
};
|
||||
|
||||
export const IdentityProjectAdditionalPrivilegeSection = ({ identityMembershipDetails }: Props) => {
|
||||
|
||||
@@ -27,13 +27,13 @@ import { ProjectPermissionActions, ProjectPermissionSub, useProject } from "@app
|
||||
import { formatProjectRoleName } from "@app/helpers/roles";
|
||||
import { usePopUp } from "@app/hooks";
|
||||
import { useUpdateProjectIdentityMembership } from "@app/hooks/api";
|
||||
import { IdentityProjectMembership } from "@app/hooks/api/identities/types";
|
||||
import { IdentityProjectMembershipV1 } from "@app/hooks/api/identities/types";
|
||||
import { TProjectRole } from "@app/hooks/api/roles/types";
|
||||
|
||||
import { IdentityRoleModify } from "./IdentityRoleModify";
|
||||
|
||||
type Props = {
|
||||
identityMembershipDetails: IdentityProjectMembership;
|
||||
identityMembershipDetails: IdentityProjectMembershipV1;
|
||||
isMembershipDetailsLoading?: boolean;
|
||||
};
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ import {
|
||||
useProjectPermission
|
||||
} from "@app/context";
|
||||
import { useGetProjectRoles, useUpdateProjectIdentityMembership } from "@app/hooks/api";
|
||||
import { IdentityProjectMembership } from "@app/hooks/api/identities/types";
|
||||
import { IdentityProjectMembershipV1 } from "@app/hooks/api/identities/types";
|
||||
import { ProjectMembershipRole } from "@app/hooks/api/roles/types";
|
||||
import { TemporaryPermissionMode } from "@app/hooks/api/shared";
|
||||
|
||||
@@ -58,7 +58,7 @@ const roleFormSchema = z.object({
|
||||
type TRoleForm = z.infer<typeof roleFormSchema>;
|
||||
|
||||
type Props = {
|
||||
identityProjectMembership: IdentityProjectMembership;
|
||||
identityProjectMembership: IdentityProjectMembershipV1;
|
||||
};
|
||||
|
||||
export const IdentityRoleModify = ({ identityProjectMembership }: Props) => {
|
||||
|
||||
@@ -31,13 +31,13 @@ import { ProjectPermissionIdentityActions, ProjectPermissionSub, useProject } fr
|
||||
import { getProjectBaseURL } from "@app/helpers/project";
|
||||
import { usePopUp, useTimedReset } from "@app/hooks";
|
||||
import { identityAuthToNameMap, TProjectIdentity, useDeleteProjectIdentity } from "@app/hooks/api";
|
||||
import { IdentityProjectMembership } from "@app/hooks/api/identities/types";
|
||||
import { IdentityProjectMembershipV1 } from "@app/hooks/api/identities/types";
|
||||
import { ProjectIdentityModal } from "@app/pages/project/AccessControlPage/components/IdentityTab/components/ProjectIdentityModal";
|
||||
|
||||
type Props = {
|
||||
identity: TProjectIdentity;
|
||||
isOrgIdentity?: boolean;
|
||||
membership: IdentityProjectMembership;
|
||||
membership: IdentityProjectMembershipV1;
|
||||
};
|
||||
|
||||
export const ProjectIdentityDetailsSection = ({ identity, isOrgIdentity, membership }: Props) => {
|
||||
|
||||
Reference in New Issue
Block a user