@@ -247,7 +247,7 @@ export class PolicyUtil {
247
247
248
248
const result : any [ ] = await this . db [ model ] . findMany ( args ) ;
249
249
250
- await Promise . all ( result . map ( ( item ) => this . postProcessForRead ( item , model , args , 'read' ) ) ) ;
250
+ await this . postProcessForRead ( result , model , args , 'read' ) ;
251
251
252
252
return result ;
253
253
}
@@ -320,54 +320,47 @@ export class PolicyUtil {
320
320
* (which can't be trimmed at query time) and removes fields that should be
321
321
* omitted.
322
322
*/
323
- async postProcessForRead ( entityData : any , model : string , args : any , operation : PolicyOperationKind ) {
324
- if ( typeof entityData !== 'object' || ! entityData ) {
325
- return ;
326
- }
327
-
328
- const ids = this . getEntityIds ( model , entityData ) ;
329
- if ( Object . keys ( ids ) . length === 0 ) {
330
- return ;
331
- }
332
-
333
- // strip auxiliary fields
334
- for ( const auxField of AUXILIARY_FIELDS ) {
335
- if ( auxField in entityData ) {
336
- delete entityData [ auxField ] ;
337
- }
338
- }
339
-
340
- const injectTarget = args . select ?? args . include ;
341
- if ( ! injectTarget ) {
342
- return ;
343
- }
344
-
345
- // to-one relation data cannot be trimmed by injected guards, we have to
346
- // post-check them
347
-
348
- for ( const field of getModelFields ( injectTarget ) ) {
349
- if ( ! entityData ?. [ field ] ) {
323
+ async postProcessForRead ( data : any , model : string , args : any , operation : PolicyOperationKind ) {
324
+ for ( const entityData of enumerate ( data ) ) {
325
+ if ( typeof entityData !== 'object' || ! entityData ) {
350
326
continue ;
351
327
}
352
328
353
- const fieldInfo = resolveField ( this . modelMeta , model , field ) ;
354
- if ( ! fieldInfo || ! fieldInfo . isDataModel || fieldInfo . isArray ) {
355
- continue ;
329
+ // strip auxiliary fields
330
+ for ( const auxField of AUXILIARY_FIELDS ) {
331
+ if ( auxField in entityData ) {
332
+ delete entityData [ auxField ] ;
333
+ }
356
334
}
357
335
358
- const ids = this . getEntityIds ( fieldInfo . type , entityData [ field ] ) ;
359
-
360
- if ( Object . keys ( ids ) . length === 0 ) {
336
+ const injectTarget = args . select ?? args . include ;
337
+ if ( ! injectTarget ) {
361
338
continue ;
362
339
}
363
340
364
- // DEBUG
365
- // this.logger.info(`Validating read of to-one relation: ${fieldInfo.type}#${formatObject(ids)}`);
341
+ // recurse into nested entities
342
+ for ( const field of Object . keys ( injectTarget ) ) {
343
+ const fieldData = entityData [ field ] ;
344
+ if ( typeof fieldData !== 'object' || ! fieldData ) {
345
+ continue ;
346
+ }
366
347
367
- await this . checkPolicyForFilter ( fieldInfo . type , ids , operation , this . db ) ;
348
+ const fieldInfo = resolveField ( this . modelMeta , model , field ) ;
349
+ if ( fieldInfo && fieldInfo . isDataModel && ! fieldInfo . isArray ) {
350
+ // to-one relation data cannot be trimmed by injected guards, we have to
351
+ // post-check them
352
+ const ids = this . getEntityIds ( fieldInfo . type , fieldData ) ;
368
353
369
- // recurse
370
- await this . postProcessForRead ( entityData [ field ] , fieldInfo . type , injectTarget [ field ] , operation ) ;
354
+ if ( Object . keys ( ids ) . length !== 0 ) {
355
+ // DEBUG
356
+ // this.logger.info(`Validating read of to-one relation: ${fieldInfo.type}#${formatObject(ids)}`);
357
+ await this . checkPolicyForFilter ( fieldInfo . type , ids , operation , this . db ) ;
358
+ }
359
+ }
360
+
361
+ // recurse
362
+ await this . postProcessForRead ( fieldData , fieldInfo . type , injectTarget [ field ] , operation ) ;
363
+ }
371
364
}
372
365
}
373
366
0 commit comments