Skip to content

Commit d2ad3a5

Browse files
committed
fix: incorrect reverse query built for to-many relation
1 parent ac3206b commit d2ad3a5

File tree

2 files changed

+73
-1
lines changed

2 files changed

+73
-1
lines changed

packages/runtime/src/enhancements/policy/policy-utils.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -525,6 +525,7 @@ export class PolicyUtil {
525525
if (backLinkField.isArray && !mutating) {
526526
// many-side of relationship, wrap with "some" query
527527
currQuery[currField.backLink] = { some: { ...visitWhere } };
528+
currQuery = currQuery[currField.backLink].some;
528529
} else {
529530
const fkMapping = where && backLinkField.isRelationOwner && backLinkField.foreignKeyMapping;
530531

@@ -553,8 +554,8 @@ export class PolicyUtil {
553554
// preserve the original structure
554555
currQuery[currField.backLink] = { ...visitWhere };
555556
}
557+
currQuery = currQuery[currField.backLink];
556558
}
557-
currQuery = currQuery[currField.backLink];
558559
currField = field;
559560
}
560561
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
import { loadSchema } from '@zenstackhq/testtools';
2+
3+
describe('Regression: issue 811', () => {
4+
it('regression', async () => {
5+
const { prisma, enhance } = await loadSchema(
6+
`
7+
model Membership {
8+
id String @id @default(uuid())
9+
role String @default('STANDARD')
10+
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
11+
userId String @unique
12+
13+
@@auth
14+
@@allow('create,update,delete', auth().role == 'ADMIN')
15+
@@allow('update', auth() == this)
16+
@@allow('read', true)
17+
}
18+
model User {
19+
id String @id @default(uuid())
20+
profile Profile @relation(fields: [profileId], references: [id], onDelete: Cascade)
21+
profileId String @unique
22+
memberships Membership[]
23+
24+
@@allow('create,update,delete', auth().role == 'ADMIN')
25+
@@allow('update', id == auth().userId)
26+
@@allow('read', true)
27+
}
28+
model Profile {
29+
id String @id @default(uuid())
30+
firstName String
31+
users User[]
32+
33+
@@allow('create,update,delete', auth().role == 'ADMIN')
34+
@@allow('update', users?[id == auth().userId])
35+
@@allow('read', true)
36+
}
37+
`
38+
);
39+
40+
const r = await prisma.user.create({
41+
data: {
42+
profile: {
43+
create: { firstName: 'Tom' },
44+
},
45+
memberships: {
46+
create: { role: 'STANDARD' },
47+
},
48+
},
49+
include: {
50+
profile: true,
51+
memberships: true,
52+
},
53+
});
54+
55+
const membershipId = r.memberships[0].id;
56+
const userId = r.id;
57+
const db = enhance({ id: membershipId, role: 'ADMIN', userId });
58+
59+
const r1 = await db.membership.update({
60+
data: {
61+
role: 'VIP',
62+
user: { update: { data: { profile: { update: { data: { firstName: 'Jerry' } } } } } },
63+
},
64+
include: { user: { include: { profile: true } } },
65+
where: { id: membershipId },
66+
});
67+
68+
expect(r1.role).toBe('VIP');
69+
expect(r1.user.profile.firstName).toBe('Jerry');
70+
});
71+
});

0 commit comments

Comments
 (0)