@@ -284,9 +284,16 @@ export class PolicyProxyHandler<DbClient extends DbClientContract> implements Pr
284
284
if ( context . field ?. backLink ) {
285
285
const backLinkField = resolveField ( this . modelMeta , model , context . field . backLink ) ;
286
286
if ( backLinkField ?. isRelationOwner ) {
287
- // the target side of relation owns the relation,
288
- // check if it's updatable
289
- await this . policyUtils . checkPolicyForUnique ( model , args . where , 'update' , db , args ) ;
287
+ // "connect" is actually "update" to foreign keys, so we need to map the "connect" payload
288
+ // to "update" payload by translating pk to fks, and use that to check update policies
289
+ const fieldsToUpdate = Object . values ( backLinkField . foreignKeyMapping ?? { } ) ;
290
+ await this . policyUtils . checkPolicyForUnique (
291
+ model ,
292
+ args . where ,
293
+ 'update' ,
294
+ db ,
295
+ fieldsToUpdate
296
+ ) ;
290
297
}
291
298
}
292
299
@@ -319,9 +326,12 @@ export class PolicyProxyHandler<DbClient extends DbClientContract> implements Pr
319
326
// check existence
320
327
await this . policyUtils . checkExistence ( db , model , args , true ) ;
321
328
322
- // the target side of relation owns the relation,
323
- // check if it's updatable
324
- await this . policyUtils . checkPolicyForUnique ( model , args , 'update' , db , args ) ;
329
+ // the target side of relation owns the relation, check if it's updatable
330
+
331
+ // "connect" is actually "update" to foreign keys, so we need to map the "connect" payload
332
+ // to "update" payload by translating pk to fks, and use that to check update policies
333
+ const fieldsToUpdate = Object . values ( backLinkField . foreignKeyMapping ?? { } ) ;
334
+ await this . policyUtils . checkPolicyForUnique ( model , args , 'update' , db , fieldsToUpdate ) ;
325
335
}
326
336
}
327
337
} ,
@@ -909,21 +919,11 @@ export class PolicyProxyHandler<DbClient extends DbClientContract> implements Pr
909
919
}
910
920
911
921
// update happens on the related model, require updatable,
912
- // translate args to foreign keys so field-level policies can be checked
913
- const checkArgs : any = { } ;
914
- if ( args && typeof args === 'object' && backLinkField . foreignKeyMapping ) {
915
- for ( const key of Object . keys ( args ) ) {
916
- const fk = backLinkField . foreignKeyMapping [ key ] ;
917
- if ( fk ) {
918
- checkArgs [ fk ] = args [ key ] ;
919
- }
920
- }
921
- }
922
-
923
922
// `uniqueFilter` can be undefined if the entity to be disconnected doesn't exist
924
923
if ( uniqueFilter ) {
925
- // check for update
926
- await this . policyUtils . checkPolicyForUnique ( model , uniqueFilter , 'update' , db , checkArgs ) ;
924
+ // check for update, "connect" and "disconnect" are actually "update" to foreign keys
925
+ const fieldsToUpdate = Object . values ( backLinkField . foreignKeyMapping ?? { } ) ;
926
+ await this . policyUtils . checkPolicyForUnique ( model , uniqueFilter , 'update' , db , fieldsToUpdate ) ;
927
927
928
928
// register post-update check
929
929
await _registerPostUpdateCheck ( model , uniqueFilter , uniqueFilter ) ;
@@ -971,12 +971,18 @@ export class PolicyProxyHandler<DbClient extends DbClientContract> implements Pr
971
971
this . policyUtils . tryReject ( db , this . model , 'update' ) ;
972
972
973
973
// check pre-update guard
974
- await this . policyUtils . checkPolicyForUnique ( model , uniqueFilter , 'update' , db , args ) ;
974
+ await this . policyUtils . checkPolicyForUnique (
975
+ model ,
976
+ uniqueFilter ,
977
+ 'update' ,
978
+ db ,
979
+ this . queryUtils . getFieldsWithDefinedValues ( updatePayload )
980
+ ) ;
975
981
976
982
// handle the case where id fields are updated
977
983
const _args : any = args ;
978
- const updatePayload = _args . data && typeof _args . data === 'object' ? _args . data : _args ;
979
- const postUpdateIds = this . calculatePostUpdateIds ( model , existing , updatePayload ) ;
984
+ const checkPayload = _args . data && typeof _args . data === 'object' ? _args . data : _args ;
985
+ const postUpdateIds = this . calculatePostUpdateIds ( model , existing , checkPayload ) ;
980
986
981
987
// register post-update check
982
988
await _registerPostUpdateCheck ( model , existing , postUpdateIds ) ;
@@ -1068,7 +1074,13 @@ export class PolicyProxyHandler<DbClient extends DbClientContract> implements Pr
1068
1074
// update case
1069
1075
1070
1076
// check pre-update guard
1071
- await this . policyUtils . checkPolicyForUnique ( model , existing , 'update' , db , args ) ;
1077
+ await this . policyUtils . checkPolicyForUnique (
1078
+ model ,
1079
+ existing ,
1080
+ 'update' ,
1081
+ db ,
1082
+ this . queryUtils . getFieldsWithDefinedValues ( args . update )
1083
+ ) ;
1072
1084
1073
1085
// handle the case where id fields are updated
1074
1086
const postUpdateIds = this . calculatePostUpdateIds ( model , existing , args . update ) ;
@@ -1156,7 +1168,7 @@ export class PolicyProxyHandler<DbClient extends DbClientContract> implements Pr
1156
1168
await this . policyUtils . checkExistence ( db , model , uniqueFilter , true ) ;
1157
1169
1158
1170
// check delete guard
1159
- await this . policyUtils . checkPolicyForUnique ( model , uniqueFilter , 'delete' , db , args ) ;
1171
+ await this . policyUtils . checkPolicyForUnique ( model , uniqueFilter , 'delete' , db , [ ] ) ;
1160
1172
} ,
1161
1173
1162
1174
deleteMany : async ( model , args , context ) => {
@@ -1526,7 +1538,7 @@ export class PolicyProxyHandler<DbClient extends DbClientContract> implements Pr
1526
1538
await this . policyUtils . checkExistence ( tx , this . model , args . where , true ) ;
1527
1539
1528
1540
// inject delete guard
1529
- await this . policyUtils . checkPolicyForUnique ( this . model , args . where , 'delete' , tx , args ) ;
1541
+ await this . policyUtils . checkPolicyForUnique ( this . model , args . where , 'delete' , tx , [ ] ) ;
1530
1542
1531
1543
// proceed with the deletion
1532
1544
if ( this . shouldLogQuery ) {
@@ -1773,7 +1785,7 @@ export class PolicyProxyHandler<DbClient extends DbClientContract> implements Pr
1773
1785
private async runPostWriteChecks ( postWriteChecks : PostWriteCheckRecord [ ] , db : CrudContract ) {
1774
1786
await Promise . all (
1775
1787
postWriteChecks . map ( async ( { model, operation, uniqueFilter, preValue } ) =>
1776
- this . policyUtils . checkPolicyForUnique ( model , uniqueFilter , operation , db , undefined , preValue )
1788
+ this . policyUtils . checkPolicyForUnique ( model , uniqueFilter , operation , db , [ ] , preValue )
1777
1789
)
1778
1790
) ;
1779
1791
}
0 commit comments