Skip to content

Commit 2141d2e

Browse files
authored
feat(policy): add settings to validate only input data for update (#2152)
1 parent 485be72 commit 2141d2e

File tree

3 files changed

+65
-1
lines changed

3 files changed

+65
-1
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -939,7 +939,7 @@ export class PolicyUtil extends QueryUtils {
939939
}
940940
}
941941

942-
if (schema) {
942+
if (schema && !this.options.validation?.inputOnlyValidationForUpdate) {
943943
// TODO: push down schema check to the database
944944
this.validateZodSchema(model, undefined, result, true, (err) => {
945945
throw this.deniedByPolicy(

packages/runtime/src/types.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,11 @@ export type EnhancementOptions = {
140140
* The encryption options for using the `encrypted` enhancement.
141141
*/
142142
encryption?: SimpleEncryption | CustomEncryption;
143+
144+
/**
145+
* Options for data validation.
146+
*/
147+
validation?: ValidationOptions;
143148
};
144149

145150
/**
@@ -209,3 +214,20 @@ export type CustomEncryption = {
209214
*/
210215
decrypt: (model: string, field: FieldInfo, cipher: string) => Promise<string>;
211216
};
217+
218+
/**
219+
* Options for data validation.
220+
*/
221+
export type ValidationOptions = {
222+
/**
223+
* Whether to validate "update" operations based only on the input data. By default, ZenStack
224+
* validates the entity after a update operation completes (inside a transaction), and rejects
225+
* the operation if validation fails. This implies the entire entity needs to satisfy the
226+
* validation rules, even for fields that are not part of the update input data.
227+
*
228+
* You can use this option to toggle the behavior to only validate the input data.
229+
*
230+
* Default is `false`.
231+
*/
232+
inputOnlyValidationForUpdate?: boolean;
233+
};
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import { loadSchema } from '@zenstackhq/testtools';
2+
3+
describe('issue 2025', () => {
4+
it('regression', async () => {
5+
const { enhanceRaw, prisma } = await loadSchema(
6+
`
7+
model User {
8+
id String @id @default(cuid())
9+
email String @unique @email
10+
termsAndConditions Int?
11+
@@allow('all', true)
12+
}
13+
`
14+
);
15+
16+
const user = await prisma.user.create({
17+
data: {
18+
email: 'xyz', // invalid email
19+
},
20+
});
21+
22+
const db = enhanceRaw(prisma, undefined, { validation: { inputOnlyValidationForUpdate: true } });
23+
await expect(
24+
db.user.update({
25+
where: { id: user.id },
26+
data: {
27+
termsAndConditions: 1,
28+
},
29+
})
30+
).toResolveTruthy();
31+
32+
const db1 = enhanceRaw(prisma);
33+
await expect(
34+
db1.user.update({
35+
where: { id: user.id },
36+
data: {
37+
termsAndConditions: 1,
38+
},
39+
})
40+
).toBeRejectedByPolicy();
41+
});
42+
});

0 commit comments

Comments
 (0)