From fe5b8cd124fc98f50363cb63100fe09331235a8e Mon Sep 17 00:00:00 2001 From: Scott Wilson Date: Fri, 19 Dec 2025 16:59:36 -0800 Subject: [PATCH] fix: fix project MI pagination, search and org identity name search regex --- .../src/server/routes/v1/identity-router.ts | 5 +++- .../membership-identity-dal.ts | 25 +++++++++++-------- .../api/projectIdentityMembership/queries.ts | 2 +- 3 files changed, 19 insertions(+), 13 deletions(-) diff --git a/backend/src/server/routes/v1/identity-router.ts b/backend/src/server/routes/v1/identity-router.ts index ba8506be4d..abe01a5e8d 100644 --- a/backend/src/server/routes/v1/identity-router.ts +++ b/backend/src/server/routes/v1/identity-router.ts @@ -20,7 +20,10 @@ const searchResourceZodValidate = zodValidateCharacters([ CharacterType.AlphaNumeric, CharacterType.Spaces, CharacterType.Underscore, - CharacterType.Hyphen + CharacterType.Hyphen, + CharacterType.ForwardSlash + // TODO: scott - adding forwardslash for quick fix but we don't constrain identity name creation - not sure why we added this but we should evaluate if needed and if so make consistent with + // the actual name limitations ]); export const registerIdentityRouter = async (server: FastifyZodProvider) => { diff --git a/backend/src/services/membership-identity/membership-identity-dal.ts b/backend/src/services/membership-identity/membership-identity-dal.ts index bcf855c882..03dab017a0 100644 --- a/backend/src/services/membership-identity/membership-identity-dal.ts +++ b/backend/src/services/membership-identity/membership-identity-dal.ts @@ -253,15 +253,12 @@ export const membershipIdentityDALFactory = (db: TDbClient) => { } }); - if (filter.limit) void paginatedIdentitys.limit(filter.limit); - if (filter.offset) void paginatedIdentitys.offset(filter.offset); - if (filter.name || filter.role) { buildKnexFilterForSearchResource( paginatedIdentitys, { - name: filter.name!, - role: filter.role! + ...(filter.name && { name: filter.name }), + ...(filter.role && { role: filter.role }) }, (attr) => { switch (attr) { @@ -276,6 +273,17 @@ export const membershipIdentityDALFactory = (db: TDbClient) => { ); } + const countQuery = await paginatedIdentitys + .clone() + .select( + db.raw( + `count(${TableName.Membership}."actorIdentityId") OVER(PARTITION BY ${TableName.Membership}."scopeOrgId") as total` + ) + ); + + if (filter.limit) void paginatedIdentitys.limit(filter.limit); + if (filter.offset) void paginatedIdentitys.offset(filter.offset); + const docs = await (tx || db.replicaNode())(TableName.Membership) .whereNotNull(`${TableName.Membership}.actorIdentityId`) .join(TableName.Identity, `${TableName.Identity}.id`, `${TableName.Membership}.actorIdentityId`) @@ -308,11 +316,6 @@ export const membershipIdentityDALFactory = (db: TDbClient) => { .as("membershipRoleTemporaryAccessEndTime"), db.ref("createdAt").withSchema(TableName.MembershipRole).as("membershipRoleCreatedAt"), db.ref("updatedAt").withSchema(TableName.MembershipRole).as("membershipRoleUpdatedAt") - ) - .select( - db.raw( - `count(${TableName.Membership}."actorIdentityId") OVER(PARTITION BY ${TableName.Membership}."scopeOrgId") as total` - ) ); const data = sqlNestRelationships({ @@ -368,7 +371,7 @@ export const membershipIdentityDALFactory = (db: TDbClient) => { } ] }); - return { data, totalCount: Number((data?.[0] as unknown as { total: number })?.total ?? 0) }; + return { data, totalCount: Number((countQuery?.[0] as unknown as { total: number })?.total ?? 0) }; } catch (error) { throw new DatabaseError({ error, name: "MembershipfindIdentity" }); } diff --git a/frontend/src/hooks/api/projectIdentityMembership/queries.ts b/frontend/src/hooks/api/projectIdentityMembership/queries.ts index 3f67f3fbf2..8b4520f19b 100644 --- a/frontend/src/hooks/api/projectIdentityMembership/queries.ts +++ b/frontend/src/hooks/api/projectIdentityMembership/queries.ts @@ -71,7 +71,7 @@ export const useListProjectIdentityMemberships = ( limit: String(limit), orderBy: String(orderBy), orderDirection: String(orderDirection), - search: String(search) + identityName: String(search) }); const { data } = await apiRequest.get(