mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-14 14:34:09 +00:00
feature: project and org identity pagination, search and sort
This commit is contained in:
@@ -363,7 +363,12 @@ export const ORGANIZATIONS = {
|
||||
membershipId: "The ID of the membership to delete."
|
||||
},
|
||||
LIST_IDENTITY_MEMBERSHIPS: {
|
||||
orgId: "The ID of the organization to get identity memberships from."
|
||||
orgId: "The ID of the organization to get identity memberships from.",
|
||||
offset: "The offset to start from. If you enter 10, it will start from the 10th identity membership.",
|
||||
limit: "The number of identity memberships to return.",
|
||||
orderBy: "The column to order identity memberships by.",
|
||||
direction: "The direction identity memberships will be sorted in.",
|
||||
textFilter: "The text string that identity membership names will be filtered by."
|
||||
},
|
||||
GET_PROJECTS: {
|
||||
organizationId: "The ID of the organization to get projects from."
|
||||
@@ -470,7 +475,12 @@ export const PROJECT_USERS = {
|
||||
|
||||
export const PROJECT_IDENTITIES = {
|
||||
LIST_IDENTITY_MEMBERSHIPS: {
|
||||
projectId: "The ID of the project to get identity memberships from."
|
||||
projectId: "The ID of the project to get identity memberships from.",
|
||||
offset: "The offset to start from. If you enter 10, it will start from the 10th identity membership.",
|
||||
limit: "The number of identity memberships to return.",
|
||||
orderBy: "The column to order identity memberships by.",
|
||||
direction: "The direction identity memberships will be sorted in.",
|
||||
textFilter: "The text string that identity membership names will be filtered by."
|
||||
},
|
||||
GET_IDENTITY_MEMBERSHIP_BY_ID: {
|
||||
identityId: "The ID of the identity to get the membership for.",
|
||||
|
||||
@@ -52,3 +52,8 @@ export enum SecretSharingAccessType {
|
||||
Anyone = "anyone",
|
||||
Organization = "organization"
|
||||
}
|
||||
|
||||
export enum OrderByDirection {
|
||||
ASC = "asc",
|
||||
DESC = "desc"
|
||||
}
|
||||
|
||||
@@ -246,12 +246,13 @@ export const registerIdentityRouter = async (server: FastifyZodProvider) => {
|
||||
description: true
|
||||
}).optional(),
|
||||
identity: IdentitiesSchema.pick({ name: true, id: true, authMethod: true })
|
||||
}).array()
|
||||
}).array(),
|
||||
totalCount: z.number()
|
||||
})
|
||||
}
|
||||
},
|
||||
handler: async (req) => {
|
||||
const identities = await server.services.identity.listOrgIdentities({
|
||||
const { identityMemberships, totalCount } = await server.services.identity.listOrgIdentities({
|
||||
actor: req.permission.type,
|
||||
actorId: req.permission.id,
|
||||
actorAuthMethod: req.permission.authMethod,
|
||||
@@ -259,7 +260,7 @@ export const registerIdentityRouter = async (server: FastifyZodProvider) => {
|
||||
orgId: req.query.orgId
|
||||
});
|
||||
|
||||
return { identities };
|
||||
return { identities: identityMemberships, totalCount };
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -2,9 +2,11 @@ import { z } from "zod";
|
||||
|
||||
import { IdentitiesSchema, IdentityOrgMembershipsSchema, OrgRolesSchema } from "@app/db/schemas";
|
||||
import { ORGANIZATIONS } from "@app/lib/api-docs";
|
||||
import { OrderByDirection } from "@app/lib/types";
|
||||
import { readLimit } from "@app/server/config/rateLimiter";
|
||||
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
|
||||
import { AuthMode } from "@app/services/auth/auth-type";
|
||||
import { OrgIdentityOrderBy } from "@app/services/identity/identity-types";
|
||||
|
||||
export const registerIdentityOrgRouter = async (server: FastifyZodProvider) => {
|
||||
server.route({
|
||||
@@ -24,6 +26,32 @@ export const registerIdentityOrgRouter = async (server: FastifyZodProvider) => {
|
||||
params: z.object({
|
||||
orgId: z.string().trim().describe(ORGANIZATIONS.LIST_IDENTITY_MEMBERSHIPS.orgId)
|
||||
}),
|
||||
querystring: z.object({
|
||||
offset: z.coerce.number().min(0).default(0).describe(ORGANIZATIONS.LIST_IDENTITY_MEMBERSHIPS.offset).optional(),
|
||||
limit: z.coerce
|
||||
.number()
|
||||
.min(1)
|
||||
.max(20000) // TODO: temp limit until combobox added to add identity to project modal, reduce once added
|
||||
.default(100)
|
||||
.describe(ORGANIZATIONS.LIST_IDENTITY_MEMBERSHIPS.limit)
|
||||
.optional(),
|
||||
orderBy: z
|
||||
.nativeEnum(OrgIdentityOrderBy)
|
||||
.default(OrgIdentityOrderBy.Name)
|
||||
.describe(ORGANIZATIONS.LIST_IDENTITY_MEMBERSHIPS.orderBy)
|
||||
.optional(),
|
||||
direction: z
|
||||
.nativeEnum(OrderByDirection)
|
||||
.default(OrderByDirection.ASC)
|
||||
.describe(ORGANIZATIONS.LIST_IDENTITY_MEMBERSHIPS.direction)
|
||||
.optional(),
|
||||
textFilter: z
|
||||
.string()
|
||||
.trim()
|
||||
.default("")
|
||||
.describe(ORGANIZATIONS.LIST_IDENTITY_MEMBERSHIPS.textFilter)
|
||||
.optional()
|
||||
}),
|
||||
response: {
|
||||
200: z.object({
|
||||
identityMemberships: IdentityOrgMembershipsSchema.merge(
|
||||
@@ -37,20 +65,26 @@ export const registerIdentityOrgRouter = async (server: FastifyZodProvider) => {
|
||||
}).optional(),
|
||||
identity: IdentitiesSchema.pick({ name: true, id: true, authMethod: true })
|
||||
})
|
||||
).array()
|
||||
).array(),
|
||||
totalCount: z.number()
|
||||
})
|
||||
}
|
||||
},
|
||||
handler: async (req) => {
|
||||
const identityMemberships = await server.services.identity.listOrgIdentities({
|
||||
const { identityMemberships, totalCount } = await server.services.identity.listOrgIdentities({
|
||||
actor: req.permission.type,
|
||||
actorId: req.permission.id,
|
||||
actorAuthMethod: req.permission.authMethod,
|
||||
actorOrgId: req.permission.orgId,
|
||||
orgId: req.params.orgId
|
||||
orgId: req.params.orgId,
|
||||
limit: req.query.limit,
|
||||
offset: req.query.offset,
|
||||
orderBy: req.query.orderBy,
|
||||
direction: req.query.direction,
|
||||
textFilter: req.query.textFilter
|
||||
});
|
||||
|
||||
return { identityMemberships };
|
||||
return { identityMemberships, totalCount };
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
@@ -7,11 +7,13 @@ import {
|
||||
ProjectMembershipRole,
|
||||
ProjectUserMembershipRolesSchema
|
||||
} from "@app/db/schemas";
|
||||
import { PROJECT_IDENTITIES } from "@app/lib/api-docs";
|
||||
import { ORGANIZATIONS, PROJECT_IDENTITIES } from "@app/lib/api-docs";
|
||||
import { BadRequestError } from "@app/lib/errors";
|
||||
import { OrderByDirection } from "@app/lib/types";
|
||||
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 { ProjectIdentityOrderBy } from "@app/services/identity-project/identity-project-types";
|
||||
import { ProjectUserMembershipTemporaryMode } from "@app/services/project-membership/project-membership-types";
|
||||
|
||||
import { SanitizedProjectSchema } from "../sanitizedSchemas";
|
||||
@@ -214,6 +216,37 @@ export const registerIdentityProjectRouter = async (server: FastifyZodProvider)
|
||||
params: z.object({
|
||||
projectId: z.string().trim().describe(PROJECT_IDENTITIES.LIST_IDENTITY_MEMBERSHIPS.projectId)
|
||||
}),
|
||||
querystring: z.object({
|
||||
offset: z.coerce
|
||||
.number()
|
||||
.min(0)
|
||||
.default(0)
|
||||
.describe(PROJECT_IDENTITIES.LIST_IDENTITY_MEMBERSHIPS.offset)
|
||||
.optional(),
|
||||
limit: z.coerce
|
||||
.number()
|
||||
.min(1)
|
||||
.max(20000) // TODO: temp limit until combobox added to add identity to project modal, reduce once added
|
||||
.default(100)
|
||||
.describe(PROJECT_IDENTITIES.LIST_IDENTITY_MEMBERSHIPS.limit)
|
||||
.optional(),
|
||||
orderBy: z
|
||||
.nativeEnum(ProjectIdentityOrderBy)
|
||||
.default(ProjectIdentityOrderBy.Name)
|
||||
.describe(ORGANIZATIONS.LIST_IDENTITY_MEMBERSHIPS.orderBy)
|
||||
.optional(),
|
||||
direction: z
|
||||
.nativeEnum(OrderByDirection)
|
||||
.default(OrderByDirection.ASC)
|
||||
.describe(ORGANIZATIONS.LIST_IDENTITY_MEMBERSHIPS.direction)
|
||||
.optional(),
|
||||
textFilter: z
|
||||
.string()
|
||||
.trim()
|
||||
.default("")
|
||||
.describe(PROJECT_IDENTITIES.LIST_IDENTITY_MEMBERSHIPS.textFilter)
|
||||
.optional()
|
||||
}),
|
||||
response: {
|
||||
200: z.object({
|
||||
identityMemberships: z
|
||||
@@ -239,19 +272,25 @@ export const registerIdentityProjectRouter = async (server: FastifyZodProvider)
|
||||
identity: IdentitiesSchema.pick({ name: true, id: true, authMethod: true }),
|
||||
project: SanitizedProjectSchema.pick({ name: true, id: true })
|
||||
})
|
||||
.array()
|
||||
.array(),
|
||||
totalCount: z.number()
|
||||
})
|
||||
}
|
||||
},
|
||||
handler: async (req) => {
|
||||
const identityMemberships = await server.services.identityProject.listProjectIdentities({
|
||||
const { identityMemberships, totalCount } = await server.services.identityProject.listProjectIdentities({
|
||||
actor: req.permission.type,
|
||||
actorId: req.permission.id,
|
||||
actorAuthMethod: req.permission.authMethod,
|
||||
actorOrgId: req.permission.orgId,
|
||||
projectId: req.params.projectId
|
||||
projectId: req.params.projectId,
|
||||
limit: req.query.limit,
|
||||
offset: req.query.offset,
|
||||
orderBy: req.query.orderBy,
|
||||
direction: req.query.direction,
|
||||
textFilter: req.query.textFilter
|
||||
});
|
||||
return { identityMemberships };
|
||||
return { identityMemberships, totalCount };
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ import { TDbClient } from "@app/db";
|
||||
import { TableName } from "@app/db/schemas";
|
||||
import { DatabaseError } from "@app/lib/errors";
|
||||
import { ormify, sqlNestRelationships } from "@app/lib/knex";
|
||||
import { TListProjectIdentityDTO } from "@app/services/identity-project/identity-project-types";
|
||||
|
||||
export type TIdentityProjectDALFactory = ReturnType<typeof identityProjectDALFactory>;
|
||||
|
||||
@@ -107,9 +108,16 @@ export const identityProjectDALFactory = (db: TDbClient) => {
|
||||
}
|
||||
};
|
||||
|
||||
const findByProjectId = async (projectId: string, filter: { identityId?: string } = {}, tx?: Knex) => {
|
||||
const findByProjectId = async (
|
||||
projectId: string,
|
||||
filter: { identityId?: string } & Pick<
|
||||
TListProjectIdentityDTO,
|
||||
"limit" | "offset" | "textFilter" | "orderBy" | "direction"
|
||||
> = {},
|
||||
tx?: Knex
|
||||
) => {
|
||||
try {
|
||||
const docs = await (tx || db.replicaNode())(TableName.IdentityProjectMembership)
|
||||
const query = (tx || db.replicaNode())(TableName.IdentityProjectMembership)
|
||||
.where(`${TableName.IdentityProjectMembership}.projectId`, projectId)
|
||||
.join(TableName.Project, `${TableName.IdentityProjectMembership}.projectId`, `${TableName.Project}.id`)
|
||||
.join(TableName.Identity, `${TableName.IdentityProjectMembership}.identityId`, `${TableName.Identity}.id`)
|
||||
@@ -117,6 +125,10 @@ export const identityProjectDALFactory = (db: TDbClient) => {
|
||||
if (filter.identityId) {
|
||||
void qb.where("identityId", filter.identityId);
|
||||
}
|
||||
|
||||
if (filter.textFilter) {
|
||||
void qb.whereILike(`${TableName.Identity}.name`, `%${filter.textFilter}%`);
|
||||
}
|
||||
})
|
||||
.join(
|
||||
TableName.IdentityProjectMembershipRole,
|
||||
@@ -154,6 +166,22 @@ export const identityProjectDALFactory = (db: TDbClient) => {
|
||||
db.ref("name").as("projectName").withSchema(TableName.Project)
|
||||
);
|
||||
|
||||
if (filter.limit) {
|
||||
void query.offset(filter.offset ?? 0).limit(filter.limit);
|
||||
}
|
||||
|
||||
if (filter.orderBy) {
|
||||
switch (filter.orderBy) {
|
||||
case "name":
|
||||
void query.orderBy(`${TableName.Identity}.${filter.orderBy}`, filter.direction);
|
||||
break;
|
||||
default:
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
|
||||
const docs = await query;
|
||||
|
||||
const members = sqlNestRelationships({
|
||||
data: docs,
|
||||
parentMapper: ({ identityId, identityName, identityAuthMethod, id, createdAt, updatedAt, projectName }) => ({
|
||||
@@ -208,9 +236,36 @@ export const identityProjectDALFactory = (db: TDbClient) => {
|
||||
}
|
||||
};
|
||||
|
||||
const getCountByProjectId = async (
|
||||
projectId: string,
|
||||
filter: { identityId?: string } & Pick<TListProjectIdentityDTO, "textFilter"> = {},
|
||||
tx?: Knex
|
||||
) => {
|
||||
try {
|
||||
const identities = await (tx || db.replicaNode())(TableName.IdentityProjectMembership)
|
||||
.where(`${TableName.IdentityProjectMembership}.projectId`, projectId)
|
||||
.join(TableName.Project, `${TableName.IdentityProjectMembership}.projectId`, `${TableName.Project}.id`)
|
||||
.join(TableName.Identity, `${TableName.IdentityProjectMembership}.identityId`, `${TableName.Identity}.id`)
|
||||
.where((qb) => {
|
||||
if (filter.identityId) {
|
||||
void qb.where("identityId", filter.identityId);
|
||||
}
|
||||
|
||||
if (filter.textFilter) {
|
||||
void qb.whereILike(`${TableName.Identity}.name`, `%${filter.textFilter}%`);
|
||||
}
|
||||
});
|
||||
|
||||
return identities.length;
|
||||
} catch (error) {
|
||||
throw new DatabaseError({ error, name: "GetCountByProjectId" });
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
...identityProjectOrm,
|
||||
findByIdentityId,
|
||||
findByProjectId
|
||||
findByProjectId,
|
||||
getCountByProjectId
|
||||
};
|
||||
};
|
||||
|
||||
@@ -268,7 +268,12 @@ export const identityProjectServiceFactory = ({
|
||||
actor,
|
||||
actorId,
|
||||
actorAuthMethod,
|
||||
actorOrgId
|
||||
actorOrgId,
|
||||
limit,
|
||||
offset,
|
||||
orderBy,
|
||||
direction,
|
||||
textFilter
|
||||
}: TListProjectIdentityDTO) => {
|
||||
const { permission } = await permissionService.getProjectPermission(
|
||||
actor,
|
||||
@@ -279,8 +284,17 @@ export const identityProjectServiceFactory = ({
|
||||
);
|
||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Identity);
|
||||
|
||||
const identityMemberships = await identityProjectDAL.findByProjectId(projectId);
|
||||
return identityMemberships;
|
||||
const identityMemberships = await identityProjectDAL.findByProjectId(projectId, {
|
||||
limit,
|
||||
offset,
|
||||
orderBy,
|
||||
direction,
|
||||
textFilter
|
||||
});
|
||||
|
||||
const totalCount = await identityProjectDAL.getCountByProjectId(projectId, { textFilter });
|
||||
|
||||
return { identityMemberships, totalCount };
|
||||
};
|
||||
|
||||
const getProjectIdentityByIdentityId = async ({
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { TProjectPermission } from "@app/lib/types";
|
||||
import { OrderByDirection, TProjectPermission } from "@app/lib/types";
|
||||
|
||||
import { ProjectUserMembershipTemporaryMode } from "../project-membership/project-membership-types";
|
||||
|
||||
@@ -40,8 +40,18 @@ export type TDeleteProjectIdentityDTO = {
|
||||
identityId: string;
|
||||
} & TProjectPermission;
|
||||
|
||||
export type TListProjectIdentityDTO = TProjectPermission;
|
||||
export type TListProjectIdentityDTO = {
|
||||
limit?: number;
|
||||
offset?: number;
|
||||
orderBy?: ProjectIdentityOrderBy;
|
||||
direction?: OrderByDirection;
|
||||
textFilter?: string;
|
||||
} & TProjectPermission;
|
||||
|
||||
export type TGetProjectIdentityByIdentityIdDTO = {
|
||||
identityId: string;
|
||||
} & TProjectPermission;
|
||||
|
||||
export enum ProjectIdentityOrderBy {
|
||||
Name = "name"
|
||||
}
|
||||
|
||||
@@ -4,6 +4,8 @@ import { TDbClient } from "@app/db";
|
||||
import { TableName, TIdentityOrgMemberships } from "@app/db/schemas";
|
||||
import { DatabaseError } from "@app/lib/errors";
|
||||
import { ormify, selectAllTableCols } from "@app/lib/knex";
|
||||
import { OrderByDirection } from "@app/lib/types";
|
||||
import { TListOrgIdentitiesByOrgIdDTO } from "@app/services/identity/identity-types";
|
||||
|
||||
export type TIdentityOrgDALFactory = ReturnType<typeof identityOrgDALFactory>;
|
||||
|
||||
@@ -27,9 +29,20 @@ export const identityOrgDALFactory = (db: TDbClient) => {
|
||||
}
|
||||
};
|
||||
|
||||
const find = async (filter: Partial<TIdentityOrgMemberships>, tx?: Knex) => {
|
||||
const find = async (
|
||||
{
|
||||
limit,
|
||||
offset = 0,
|
||||
orderBy,
|
||||
direction = OrderByDirection.ASC,
|
||||
textFilter,
|
||||
...filter
|
||||
}: Partial<TIdentityOrgMemberships> &
|
||||
Pick<TListOrgIdentitiesByOrgIdDTO, "offset" | "limit" | "orderBy" | "direction" | "textFilter">,
|
||||
tx?: Knex
|
||||
) => {
|
||||
try {
|
||||
const docs = await (tx || db.replicaNode())(TableName.IdentityOrgMembership)
|
||||
const query = (tx || db.replicaNode())(TableName.IdentityOrgMembership)
|
||||
.where(filter)
|
||||
.join(TableName.Identity, `${TableName.IdentityOrgMembership}.identityId`, `${TableName.Identity}.id`)
|
||||
.leftJoin(TableName.OrgRoles, `${TableName.IdentityOrgMembership}.roleId`, `${TableName.OrgRoles}.id`)
|
||||
@@ -44,6 +57,30 @@ export const identityOrgDALFactory = (db: TDbClient) => {
|
||||
.select(db.ref("id").as("identityId").withSchema(TableName.Identity))
|
||||
.select(db.ref("name").as("identityName").withSchema(TableName.Identity))
|
||||
.select(db.ref("authMethod").as("identityAuthMethod").withSchema(TableName.Identity));
|
||||
|
||||
if (limit) {
|
||||
void query.offset(offset).limit(limit);
|
||||
}
|
||||
|
||||
if (orderBy) {
|
||||
switch (orderBy) {
|
||||
case "name":
|
||||
void query.orderBy(`${TableName.Identity}.${orderBy}`, direction);
|
||||
break;
|
||||
case "role":
|
||||
void query.orderBy(`${TableName.IdentityOrgMembership}.${orderBy}`, direction);
|
||||
break;
|
||||
default:
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
|
||||
if (textFilter?.length) {
|
||||
void query.whereILike(`${TableName.Identity}.name`, `%${textFilter}%`);
|
||||
}
|
||||
|
||||
const docs = await query;
|
||||
|
||||
return docs.map(
|
||||
({
|
||||
crId,
|
||||
@@ -79,5 +116,26 @@ export const identityOrgDALFactory = (db: TDbClient) => {
|
||||
}
|
||||
};
|
||||
|
||||
return { ...identityOrgOrm, find, findOne };
|
||||
const countAllOrgIdentities = async (
|
||||
{ textFilter, ...filter }: Partial<TIdentityOrgMemberships> & Pick<TListOrgIdentitiesByOrgIdDTO, "textFilter">,
|
||||
tx?: Knex
|
||||
) => {
|
||||
try {
|
||||
const query = (tx || db.replicaNode())(TableName.IdentityOrgMembership)
|
||||
.where(filter)
|
||||
.join(TableName.Identity, `${TableName.IdentityOrgMembership}.identityId`, `${TableName.Identity}.id`);
|
||||
|
||||
if (textFilter?.length) {
|
||||
void query.whereILike(`${TableName.Identity}.name`, `%${textFilter}%`);
|
||||
}
|
||||
|
||||
const identities = await query;
|
||||
|
||||
return identities.length;
|
||||
} catch (error) {
|
||||
throw new DatabaseError({ error, name: "countAllOrgIdentities" });
|
||||
}
|
||||
};
|
||||
|
||||
return { ...identityOrgOrm, find, findOne, countAllOrgIdentities };
|
||||
};
|
||||
|
||||
@@ -6,7 +6,6 @@ import { OrgPermissionActions, OrgPermissionSubjects } from "@app/ee/services/pe
|
||||
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service";
|
||||
import { isAtLeastAsPrivileged } from "@app/lib/casl";
|
||||
import { BadRequestError, ForbiddenRequestError, NotFoundError } from "@app/lib/errors";
|
||||
import { TOrgPermission } from "@app/lib/types";
|
||||
import { TIdentityProjectDALFactory } from "@app/services/identity-project/identity-project-dal";
|
||||
|
||||
import { ActorType } from "../auth/auth-type";
|
||||
@@ -16,6 +15,7 @@ import {
|
||||
TCreateIdentityDTO,
|
||||
TDeleteIdentityDTO,
|
||||
TGetIdentityByIdDTO,
|
||||
TListOrgIdentitiesByOrgIdDTO,
|
||||
TListProjectIdentitiesByIdentityIdDTO,
|
||||
TUpdateIdentityDTO
|
||||
} from "./identity-types";
|
||||
@@ -195,14 +195,36 @@ export const identityServiceFactory = ({
|
||||
return { ...deletedIdentity, orgId: identityOrgMembership.orgId };
|
||||
};
|
||||
|
||||
const listOrgIdentities = async ({ orgId, actor, actorId, actorAuthMethod, actorOrgId }: TOrgPermission) => {
|
||||
const listOrgIdentities = async ({
|
||||
orgId,
|
||||
actor,
|
||||
actorId,
|
||||
actorAuthMethod,
|
||||
actorOrgId,
|
||||
limit,
|
||||
offset,
|
||||
orderBy,
|
||||
direction,
|
||||
textFilter
|
||||
}: TListOrgIdentitiesByOrgIdDTO) => {
|
||||
const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorAuthMethod, actorOrgId);
|
||||
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Identity);
|
||||
|
||||
const identityMemberships = await identityOrgMembershipDAL.find({
|
||||
[`${TableName.IdentityOrgMembership}.orgId` as "orgId"]: orgId
|
||||
[`${TableName.IdentityOrgMembership}.orgId` as "orgId"]: orgId,
|
||||
limit,
|
||||
offset,
|
||||
orderBy,
|
||||
direction,
|
||||
textFilter
|
||||
});
|
||||
return identityMemberships;
|
||||
|
||||
const totalCount = await identityOrgMembershipDAL.countAllOrgIdentities({
|
||||
[`${TableName.IdentityOrgMembership}.orgId` as "orgId"]: orgId,
|
||||
textFilter
|
||||
});
|
||||
|
||||
return { identityMemberships, totalCount };
|
||||
};
|
||||
|
||||
const listProjectIdentitiesByIdentityId = async ({
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { IPType } from "@app/lib/ip";
|
||||
import { TOrgPermission } from "@app/lib/types";
|
||||
import { OrderByDirection, TOrgPermission } from "@app/lib/types";
|
||||
|
||||
export type TCreateIdentityDTO = {
|
||||
role: string;
|
||||
@@ -29,3 +29,16 @@ export interface TIdentityTrustedIp {
|
||||
export type TListProjectIdentitiesByIdentityIdDTO = {
|
||||
identityId: string;
|
||||
} & Omit<TOrgPermission, "orgId">;
|
||||
|
||||
export type TListOrgIdentitiesByOrgIdDTO = {
|
||||
limit?: number;
|
||||
offset?: number;
|
||||
orderBy?: OrgIdentityOrderBy;
|
||||
direction?: OrderByDirection;
|
||||
textFilter?: string;
|
||||
} & TOrgPermission;
|
||||
|
||||
export enum OrgIdentityOrderBy {
|
||||
Name = "name",
|
||||
Role = "role"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user