Skip to content

Commit 876e013

Browse files
authored
fix: incorrect policy injection for nested to-one relation inside a to-many parent (#777)
1 parent 916d3c1 commit 876e013

File tree

4 files changed

+102
-3
lines changed

4 files changed

+102
-3
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -515,7 +515,7 @@ export class PolicyUtil {
515515
throw this.unknownError(`missing backLink field ${currField.backLink} in ${currField.type}`);
516516
}
517517

518-
if (backLinkField.isArray) {
518+
if (backLinkField.isArray && !mutating) {
519519
// many-side of relationship, wrap with "some" query
520520
currQuery[currField.backLink] = { some: { ...visitWhere } };
521521
} else {

tests/integration/tests/cli/plugins.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ describe('CLI Plugins Tests', () => {
7171
7272
'react',
7373
'swr',
74-
'@tanstack/react-query',
74+
'@tanstack/react-query@^4.0.0',
7575
'@trpc/server',
7676
'@prisma/client@^4.0.0',
7777
`${path.join(__dirname, '../../../../.build/zenstackhq-language-' + ver + '.tgz')}`,

tests/integration/tests/enhancements/with-policy/nested-to-many.test.ts

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,7 @@ describe('With Policy:nested to-many', () => {
284284
expect(r.m2).toEqual(expect.arrayContaining([expect.objectContaining({ id: '2', value: 3 })]));
285285
});
286286

287-
it('update with create', async () => {
287+
it('update with create from one to many', async () => {
288288
const { withPolicy } = await loadSchema(
289289
`
290290
model M1 {
@@ -341,6 +341,56 @@ describe('With Policy:nested to-many', () => {
341341
expect(r.m2).toHaveLength(3);
342342
});
343343

344+
it('update with create from many to one', async () => {
345+
const { withPolicy } = await loadSchema(
346+
`
347+
model M1 {
348+
id String @id @default(uuid())
349+
value Int
350+
m2 M2[]
351+
352+
@@allow('read', true)
353+
@@allow('create', value > 0)
354+
@@allow('update', value > 1)
355+
}
356+
357+
model M2 {
358+
id String @id @default(uuid())
359+
m1 M1? @relation(fields: [m1Id], references:[id])
360+
m1Id String?
361+
362+
@@allow('all', true)
363+
}
364+
`
365+
);
366+
367+
const db = withPolicy();
368+
369+
await db.m2.create({ data: { id: '1' } });
370+
371+
await expect(
372+
db.m2.update({
373+
where: { id: '1' },
374+
data: {
375+
m1: {
376+
create: { value: 0 },
377+
},
378+
},
379+
})
380+
).toBeRejectedByPolicy();
381+
382+
await expect(
383+
db.m2.update({
384+
where: { id: '1' },
385+
data: {
386+
m1: {
387+
create: { value: 1 },
388+
},
389+
},
390+
})
391+
).toResolveTruthy();
392+
});
393+
344394
it('update with delete', async () => {
345395
const { withPolicy, prisma } = await loadSchema(
346396
`
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import { loadSchema } from '@zenstackhq/testtools';
2+
3+
describe('Regression: issue 764', () => {
4+
it('regression', async () => {
5+
const { prisma, enhance } = await loadSchema(
6+
`
7+
model User {
8+
id Int @id @default(autoincrement())
9+
name String
10+
11+
post Post? @relation(fields: [postId], references: [id])
12+
postId Int?
13+
14+
@@allow('all', true)
15+
}
16+
17+
model Post {
18+
id Int @id @default(autoincrement())
19+
title String
20+
User User[]
21+
22+
@@allow('all', true)
23+
}
24+
`
25+
);
26+
27+
const db = enhance();
28+
29+
const user = await prisma.user.create({
30+
data: { name: 'Me' },
31+
});
32+
33+
await db.user.update({
34+
where: { id: user.id },
35+
data: {
36+
post: {
37+
upsert: {
38+
create: {
39+
title: 'Hello World',
40+
},
41+
update: {
42+
title: 'Hello World',
43+
},
44+
},
45+
},
46+
},
47+
});
48+
});
49+
});

0 commit comments

Comments
 (0)