Skip to content

Commit 50b01fe

Browse files
committed
fix(policy): Prisma extension computed fields are not returned when fields level polices are used
fixes #2104
1 parent 00344ad commit 50b01fe

File tree

2 files changed

+84
-36
lines changed

2 files changed

+84
-36
lines changed

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

Lines changed: 31 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1204,47 +1204,42 @@ export class PolicyUtil extends QueryUtils {
12041204
return;
12051205
}
12061206

1207-
let target: any; // injection target
1208-
let isInclude = false; // if the target is include or select
1209-
1210-
if (args.select) {
1211-
target = args.select;
1212-
isInclude = false;
1213-
} else if (args.include) {
1214-
target = args.include;
1215-
isInclude = true;
1216-
} else {
1217-
target = args.select = this.makeAllScalarFieldSelect(model);
1218-
isInclude = false;
1219-
}
1220-
1221-
if (!isInclude) {
1222-
// merge selects
1223-
for (const [k, v] of Object.entries(input.select)) {
1224-
if (v === true) {
1225-
if (!target[k]) {
1226-
target[k] = true;
1227-
}
1207+
// process scalar field selections first
1208+
for (const [k, v] of Object.entries<any>(input.select)) {
1209+
const field = resolveField(this.modelMeta, model, k);
1210+
if (!field || field.isDataModel) {
1211+
continue;
1212+
}
1213+
if (v === true) {
1214+
if (!args.select) {
1215+
// do nothing since all scalar fields are selected by default
1216+
} else if (args.include) {
1217+
// do nothing since include implies selecting all scalar fields
1218+
} else {
1219+
args.select[k] = true;
12281220
}
12291221
}
12301222
}
12311223

1232-
// recurse into nested selects (relation fields)
1224+
// process relation selections
12331225
for (const [k, v] of Object.entries<any>(input.select)) {
1234-
if (typeof v === 'object' && v?.select) {
1235-
const field = resolveField(this.modelMeta, model, k);
1236-
if (field?.isDataModel) {
1237-
// recurse into relation
1238-
if (isInclude && target[k] === true) {
1239-
// select all fields for the relation
1240-
target[k] = { select: this.makeAllScalarFieldSelect(field.type) };
1241-
} else if (!target[k]) {
1242-
// ensure an empty select clause
1243-
target[k] = { select: {} };
1244-
}
1245-
// recurse
1246-
this.doInjectReadCheckSelect(field.type, target[k], v);
1247-
}
1226+
const field = resolveField(this.modelMeta, model, k);
1227+
if (!field || !field.isDataModel) {
1228+
continue;
1229+
}
1230+
1231+
// prepare the next level of args
1232+
let nextArgs = args.select ?? args.include;
1233+
if (!nextArgs) {
1234+
nextArgs = args.include = {};
1235+
}
1236+
if (!nextArgs[k] || typeof nextArgs[k] !== 'object') {
1237+
nextArgs[k] = {};
1238+
}
1239+
1240+
if (v && typeof v === 'object') {
1241+
// recurse into relation
1242+
this.doInjectReadCheckSelect(field.type, nextArgs[k], v);
12481243
}
12491244
}
12501245
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import { loadSchema } from '@zenstackhq/testtools';
2+
3+
describe('issue 2104', () => {
4+
it('regression', async () => {
5+
const { enhance } = await loadSchema(
6+
`
7+
model Post {
8+
id Int @id @default(autoincrement())
9+
tickets TicketInPost[]
10+
@@allow('all', true)
11+
}
12+
13+
model View {
14+
id Int @id @default(autoincrement())
15+
ability String
16+
tickets TicketInPost[]
17+
@@allow('all', true)
18+
}
19+
20+
model TicketInPost {
21+
id Int @id @default(autoincrement())
22+
postId Int
23+
post Post @relation(fields: [postId], references: [id])
24+
viewId Int
25+
view View @relation(fields: [viewId], references: [id])
26+
@@allow('all', true)
27+
}
28+
`,
29+
{ logPrismaQuery: true, enhancements: ['policy', 'delegate'] }
30+
);
31+
32+
const db = enhance();
33+
const view = await db.view.create({ data: { ability: 'bla' } });
34+
const post = await db.post.create({ data: {} });
35+
const updatedPost = await db.post.update({
36+
where: {
37+
id: post.id,
38+
},
39+
data: {
40+
tickets: {
41+
deleteMany: {},
42+
create: {
43+
viewId: view.id,
44+
},
45+
},
46+
},
47+
include: {
48+
tickets: true,
49+
},
50+
});
51+
console.log('created!', updatedPost);
52+
});
53+
});

0 commit comments

Comments
 (0)