1- import { ExecutionContext } from '@nestjs/common'
1+ import { ExecutionContext , Inject , Optional } from '@nestjs/common'
22import { Args , ArgsType , Context , Parent , Resolver } from '@nestjs/graphql'
3- import { Class , Filter , mergeQuery , QueryService } from '@ptc-org/nestjs-query-core'
3+ import { Class , mergeQuery , QueryService } from '@ptc-org/nestjs-query-core'
44
5- import { OperationGroup } from '../../auth'
5+ import { Authorizer , getAuthorizerToken , OperationGroup } from '../../auth'
66import { getDTONames } from '../../common'
7- import { GraphQLResolveInfoResult , GraphQLResultInfo , RelationAuthorizerFilter , ResolverField } from '../../decorators'
7+ import { GraphQLResolveInfoResult , GraphQLResultInfo , ResolverField } from '../../decorators'
88import { InjectDataLoaderConfig } from '../../decorators/inject-dataloader-config.decorator'
99import { AuthorizerInterceptor } from '../../interceptors'
1010import { CountRelationsLoader , DataLoaderFactory , FindRelationsLoader , QueryRelationsLoader } from '../../loader'
@@ -30,10 +30,16 @@ const ReadOneRelationMixin =
3030 const { baseNameLower, baseName } = getDTONames ( relationDTO , { dtoName : relation . dtoName } )
3131 const relationName = relation . relationName ?? baseNameLower
3232 const loaderName = `load${ baseName } For${ DTOClass . name } `
33+ const authorizerKey = Symbol ( `authorizerFor${ DTOClass . name } ` )
34+ const relationAuthorizerKey = Symbol ( `authorizerFor${ relation . dtoName } ` )
3335 const findLoader = new FindRelationsLoader < DTO , Relation > ( relationDTO , relationName )
3436
3537 @Resolver ( ( ) => DTOClass , { isAbstract : true } )
3638 class ReadOneMixin extends Base {
39+ @Optional ( ) @Inject ( getAuthorizerToken ( DTOClass ) ) [ authorizerKey ] ?: Authorizer < Relation > ;
40+
41+ @Optional ( ) @Inject ( getAuthorizerToken ( relationDTO ) ) [ relationAuthorizerKey ] ?: Authorizer < Relation >
42+
3743 @ResolverField (
3844 baseNameLower ,
3945 ( ) => relationDTO ,
@@ -49,16 +55,21 @@ const ReadOneRelationMixin =
4955 async [ `find${ baseName } ` ] (
5056 @Parent ( ) dto : DTO ,
5157 @Context ( ) context : ExecutionContext ,
52- @RelationAuthorizerFilter ( baseNameLower , {
53- operationGroup : OperationGroup . READ ,
54- many : false
55- } )
56- authFilter ?: Filter < Relation > ,
5758 @GraphQLResultInfo ( DTOClass )
5859 resolveInfo ?: GraphQLResolveInfoResult < Relation > ,
5960 @InjectDataLoaderConfig ( )
6061 dataLoaderConfig ?: DataLoaderOptions
6162 ) : Promise < Relation | undefined > {
63+ const authContext = {
64+ operationName : baseNameLower ,
65+ operationGroup : OperationGroup . READ ,
66+ readonly : true ,
67+ many : false
68+ }
69+ const authFilter = relation . auth
70+ ? await relation . auth ?. authorize ( context , authContext )
71+ : ( ( await this [ authorizerKey ] ?. authorizeRelation ( baseNameLower , context , authContext ) ) ??
72+ ( await this [ relationAuthorizerKey ] ?. authorize ( context , authContext ) ) )
6273 return DataLoaderFactory . getOrCreateLoader (
6374 context ,
6475 loaderName ,
@@ -93,6 +104,8 @@ const ReadManyRelationMixin =
93104 const relationName = relation . relationName ?? baseNameLower
94105 const relationLoaderName = `load${ baseName } For${ DTOClass . name } `
95106 const countRelationLoaderName = `count${ baseName } For${ DTOClass . name } `
107+ const authorizerKey = Symbol ( `authorizerFor${ DTOClass . name } ` )
108+ const relationAuthorizerKey = Symbol ( `authorizerFor${ relation . dtoName } ` )
96109 const queryLoader = new QueryRelationsLoader < DTO , Relation > ( relationDTO , relationName )
97110 const countLoader = new CountRelationsLoader < DTO , Relation > ( relationDTO , relationName )
98111 const connectionName = `${ dtoName } ${ baseName } Connection`
@@ -109,6 +122,10 @@ const ReadManyRelationMixin =
109122
110123 @Resolver ( ( ) => DTOClass , { isAbstract : true } )
111124 class ReadManyMixin extends Base {
125+ @Optional ( ) @Inject ( getAuthorizerToken ( DTOClass ) ) [ authorizerKey ] ?: Authorizer < Relation > ;
126+
127+ @Optional ( ) @Inject ( getAuthorizerToken ( relationDTO ) ) [ relationAuthorizerKey ] ?: Authorizer < Relation >
128+
112129 @ResolverField (
113130 baseNameLower ,
114131 ( ) => CT . resolveType ,
@@ -125,16 +142,21 @@ const ReadManyRelationMixin =
125142 @Parent ( ) dto : DTO ,
126143 @Args ( ) q : RelationQA ,
127144 @Context ( ) context : ExecutionContext ,
128- @RelationAuthorizerFilter ( baseNameLower , {
129- operationGroup : OperationGroup . READ ,
130- many : true
131- } )
132- relationFilter ?: Filter < Relation > ,
133145 @GraphQLResultInfo ( DTOClass )
134146 resolveInfo ?: GraphQLResolveInfoResult < Relation > ,
135147 @InjectDataLoaderConfig ( )
136148 dataLoaderConfig ?: DataLoaderOptions
137149 ) : Promise < InstanceType < typeof CT > > {
150+ const authContext = {
151+ operationName : baseNameLower ,
152+ operationGroup : OperationGroup . READ ,
153+ readonly : true ,
154+ many : true
155+ }
156+ const authFilter = relation . auth
157+ ? await relation . auth ?. authorize ( context , authContext )
158+ : ( ( await this [ authorizerKey ] ?. authorizeRelation ( baseNameLower , context , authContext ) ) ??
159+ ( await this [ relationAuthorizerKey ] ?. authorize ( context , authContext ) ) )
138160 const relationQuery = await transformAndValidate ( RelationQA , q )
139161 const relationLoader = DataLoaderFactory . getOrCreateLoader (
140162 context ,
@@ -152,7 +174,7 @@ const ReadManyRelationMixin =
152174
153175 return CT . createFromPromise (
154176 ( query ) => relationLoader . load ( { dto, query } ) ,
155- mergeQuery ( relationQuery , { filter : relationFilter , relations : resolveInfo ?. relations } ) ,
177+ mergeQuery ( relationQuery , { filter : authFilter , relations : resolveInfo ?. relations } ) ,
156178 ( filter ) => relationCountLoader . load ( { dto, filter } )
157179 )
158180 }
0 commit comments