fix(org): match listMyProjects grants by principal pair

Filtering permission grants with separate principalType/principalId IN
lists matched cross-product rows (e.g. TEAM + user id). Use OR of exact
(type, id) pairs so members only see projects their principals hold.
This commit is contained in:
2026-07-14 23:55:20 +08:00
parent 4ad0259193
commit 1d2f4657ba
+7 -6
View File
@@ -350,16 +350,17 @@ export async function listMyProjects(
{ feishuOpenId: input.actorFeishuOpenId }, { feishuOpenId: input.actorFeishuOpenId },
{ organizationId: input.organizationId }, { organizationId: input.organizationId },
); );
const principalKeys = resolution.principals.map((p) => `${p.type}:${p.id}`); // Match exact (type, id) pairs — independent IN filters form a cartesian
if (principalKeys.length === 0) return []; // product and can attribute another principal's grants to this actor.
const principalTypes = resolution.principals.map((p) => p.type); if (resolution.principals.length === 0) return [];
const principalIds = resolution.principals.map((p) => p.id);
const grants = await prisma.permissionGrant.findMany({ const grants = await prisma.permissionGrant.findMany({
where: { where: {
resourceType: "PROJECT", resourceType: "PROJECT",
revokedAt: null, revokedAt: null,
principalType: { in: principalTypes }, OR: resolution.principals.map((p) => ({
principalId: { in: principalIds }, principalType: p.type,
principalId: p.id,
})),
}, },
select: { resourceId: true }, select: { resourceId: true },
distinct: ["resourceId"], distinct: ["resourceId"],