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 };
|
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,
|
TCreateProjectIdentityDTO,
|
||||||
TDeleteProjectIdentityDTO,
|
TDeleteProjectIdentityDTO,
|
||||||
TGetProjectIdentityByIdentityIdDTO,
|
TGetProjectIdentityByIdentityIdDTO,
|
||||||
|
TGetProjectIdentityByMembershipIdDTO,
|
||||||
TListProjectIdentityDTO,
|
TListProjectIdentityDTO,
|
||||||
TUpdateProjectIdentityDTO
|
TUpdateProjectIdentityDTO
|
||||||
} from "./identity-project-types";
|
} from "./identity-project-types";
|
||||||
@@ -370,11 +371,48 @@ export const identityProjectServiceFactory = ({
|
|||||||
return identityMembership;
|
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 {
|
return {
|
||||||
createProjectIdentity,
|
createProjectIdentity,
|
||||||
updateProjectIdentity,
|
updateProjectIdentity,
|
||||||
deleteProjectIdentity,
|
deleteProjectIdentity,
|
||||||
listProjectIdentities,
|
listProjectIdentities,
|
||||||
getProjectIdentityByIdentityId
|
getProjectIdentityByIdentityId,
|
||||||
|
getProjectIdentityByMembershipId
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -52,6 +52,10 @@ export type TGetProjectIdentityByIdentityIdDTO = {
|
|||||||
identityId: string;
|
identityId: string;
|
||||||
} & TProjectPermission;
|
} & TProjectPermission;
|
||||||
|
|
||||||
|
export type TGetProjectIdentityByMembershipIdDTO = {
|
||||||
|
identityMembershipId: string;
|
||||||
|
} & Omit<TProjectPermission, "projectId">;
|
||||||
|
|
||||||
export enum ProjectIdentityOrderBy {
|
export enum ProjectIdentityOrderBy {
|
||||||
Name = "name"
|
Name = "name"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -86,7 +86,20 @@ const Page = () => {
|
|||||||
title={identityMembershipDetails?.identity?.name}
|
title={identityMembershipDetails?.identity?.name}
|
||||||
description={`Identity joined on ${identityMembershipDetails?.createdAt && formatRelative(new Date(identityMembershipDetails?.createdAt || ""), new Date())}`}
|
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
|
<ProjectPermissionCan
|
||||||
I={ProjectPermissionActions.Delete}
|
I={ProjectPermissionActions.Delete}
|
||||||
a={subject(ProjectPermissionSub.Identity, {
|
a={subject(ProjectPermissionSub.Identity, {
|
||||||
|
|||||||
Reference in New Issue
Block a user