mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-09-22 13:39:35 +00:00
Merge pull request #3389 from Infisical/daniel/get-project-identity-membership-by-id
feat(project-identity): get project identity by membership ID
This commit is contained in:
@@ -351,4 +351,56 @@ export const registerIdentityProjectRouter = async (server: FastifyZodProvider)
|
||||
return { identityMembership };
|
||||
}
|
||||
});
|
||||
|
||||
server.route({
|
||||
method: "GET",
|
||||
url: "/identity-memberships/:identityMembershipId",
|
||||
config: {
|
||||
rateLimit: readLimit
|
||||
},
|
||||
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
|
||||
schema: {
|
||||
params: z.object({
|
||||
identityMembershipId: z.string().trim()
|
||||
}),
|
||||
response: {
|
||||
200: z.object({
|
||||
identityMembership: z.object({
|
||||
id: z.string(),
|
||||
identityId: z.string(),
|
||||
createdAt: z.date(),
|
||||
updatedAt: z.date(),
|
||||
roles: z.array(
|
||||
z.object({
|
||||
id: z.string(),
|
||||
role: z.string(),
|
||||
customRoleId: z.string().optional().nullable(),
|
||||
customRoleName: z.string().optional().nullable(),
|
||||
customRoleSlug: z.string().optional().nullable(),
|
||||
isTemporary: z.boolean(),
|
||||
temporaryMode: z.string().optional().nullable(),
|
||||
temporaryRange: z.string().nullable().optional(),
|
||||
temporaryAccessStartTime: z.date().nullable().optional(),
|
||||
temporaryAccessEndTime: z.date().nullable().optional()
|
||||
})
|
||||
),
|
||||
identity: IdentitiesSchema.pick({ name: true, id: true }).extend({
|
||||
authMethods: z.array(z.string())
|
||||
}),
|
||||
project: SanitizedProjectSchema.pick({ name: true, id: true })
|
||||
})
|
||||
})
|
||||
}
|
||||
},
|
||||
handler: async (req) => {
|
||||
const identityMembership = await server.services.identityProject.getProjectIdentityByMembershipId({
|
||||
actor: req.permission.type,
|
||||
actorId: req.permission.id,
|
||||
actorAuthMethod: req.permission.authMethod,
|
||||
actorOrgId: req.permission.orgId,
|
||||
identityMembershipId: req.params.identityMembershipId
|
||||
});
|
||||
return { identityMembership };
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
@@ -21,6 +21,7 @@ import {
|
||||
TCreateProjectIdentityDTO,
|
||||
TDeleteProjectIdentityDTO,
|
||||
TGetProjectIdentityByIdentityIdDTO,
|
||||
TGetProjectIdentityByMembershipIdDTO,
|
||||
TListProjectIdentityDTO,
|
||||
TUpdateProjectIdentityDTO
|
||||
} from "./identity-project-types";
|
||||
@@ -370,11 +371,48 @@ export const identityProjectServiceFactory = ({
|
||||
return identityMembership;
|
||||
};
|
||||
|
||||
const getProjectIdentityByMembershipId = async ({
|
||||
identityMembershipId,
|
||||
actor,
|
||||
actorId,
|
||||
actorAuthMethod,
|
||||
actorOrgId
|
||||
}: TGetProjectIdentityByMembershipIdDTO) => {
|
||||
const membership = await identityProjectDAL.findOne({ id: identityMembershipId });
|
||||
|
||||
if (!membership) {
|
||||
throw new NotFoundError({
|
||||
message: `Project membership with ID '${identityMembershipId}' not found`
|
||||
});
|
||||
}
|
||||
|
||||
const { permission } = await permissionService.getProjectPermission({
|
||||
actor,
|
||||
actorId,
|
||||
projectId: membership.projectId,
|
||||
actorAuthMethod,
|
||||
actorOrgId,
|
||||
actionProjectType: ActionProjectType.Any
|
||||
});
|
||||
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
ProjectPermissionIdentityActions.Read,
|
||||
subject(ProjectPermissionSub.Identity, { identityId: membership.identityId })
|
||||
);
|
||||
|
||||
const [identityMembership] = await identityProjectDAL.findByProjectId(membership.projectId, {
|
||||
identityId: membership.identityId
|
||||
});
|
||||
|
||||
return identityMembership;
|
||||
};
|
||||
|
||||
return {
|
||||
createProjectIdentity,
|
||||
updateProjectIdentity,
|
||||
deleteProjectIdentity,
|
||||
listProjectIdentities,
|
||||
getProjectIdentityByIdentityId
|
||||
getProjectIdentityByIdentityId,
|
||||
getProjectIdentityByMembershipId
|
||||
};
|
||||
};
|
||||
|
||||
@@ -52,6 +52,10 @@ export type TGetProjectIdentityByIdentityIdDTO = {
|
||||
identityId: string;
|
||||
} & TProjectPermission;
|
||||
|
||||
export type TGetProjectIdentityByMembershipIdDTO = {
|
||||
identityMembershipId: string;
|
||||
} & Omit<TProjectPermission, "projectId">;
|
||||
|
||||
export enum ProjectIdentityOrderBy {
|
||||
Name = "name"
|
||||
}
|
||||
|
||||
@@ -86,7 +86,20 @@ const Page = () => {
|
||||
title={identityMembershipDetails?.identity?.name}
|
||||
description={`Identity joined on ${identityMembershipDetails?.createdAt && formatRelative(new Date(identityMembershipDetails?.createdAt || ""), new Date())}`}
|
||||
>
|
||||
<div>
|
||||
<div className="flex items-center gap-2">
|
||||
<Button
|
||||
variant="outline_bg"
|
||||
size="xs"
|
||||
onClick={() => {
|
||||
navigator.clipboard.writeText(identityMembershipDetails.id);
|
||||
createNotification({
|
||||
text: "Membership ID copied to clipboard",
|
||||
type: "success"
|
||||
});
|
||||
}}
|
||||
>
|
||||
Copy Membership ID
|
||||
</Button>
|
||||
<ProjectPermissionCan
|
||||
I={ProjectPermissionActions.Delete}
|
||||
a={subject(ProjectPermissionSub.Identity, {
|
||||
|
||||
Reference in New Issue
Block a user