import { Injectable } from '@nestjs/common' ; import { IRoleRbac } from './interfaces/role.rbac.interface' ; import { IFilterPermission } from '../permissions/interfaces/filter.permission.interface' ; import { IParamsFilter } from '../params-filter/interfaces/params.filter.interface' ; @ Injectable ( ) export class RoleRbac implements IRoleRbac { constructor ( private readonly role , private readonly grant , private readonly filters , private readonly paramsFilter ? ) { } canAsync ( ... permissions ) { return this . checkPermissions < Promise < boolean > > ( permissions , 'canAsync' ) ; } can ( ... permissions ) { return this . checkPermissions < boolean > ( permissions , 'can' ) ; } any ( ... permissions ) { return ( permissions . map ( permission => { return this . can ( ... permission ) ; } ) . some ( result => result ) ) ; } async anyAsync ( ... permissions ) { return ( await Promise . all ( permissions . map ( permission => { return this . canAsync ( ... permission ) ; } ) ) ) . some ( result => result ) ; } private checkPermissions < T > ( permissions , methodName ) { if ( ! permissions . length ) { return false as any ; } for ( const permission of permissions ) { if ( ! this . grant . includes ( permission ) ) { return false as any ; } } for ( const permission of permissions ) { if ( this . grant . includes ( permission ) && permission . includes ( '@' ) ) { const filter = permission . split ( '@' ) [ 1 ] ; const filterService = this . filters [ filter ] ; if ( filterService ) { return ( filterService ?. [ methodName ] ?. ( this . paramsFilter ? this . paramsFilter . getParam ( filter ) : null ) ?? true ) ; } } if ( this . grant . includes ( permission ) && ! permission . includes ( '@' ) ) { for ( const filter in this . filters ) { if ( this . filters . hasOwnProperty ( filter ) && this . grant . includes ( `${ permission }@${ filter }` ) ) { return ( this . filters [ filter ] ?. [ methodName ] ?. ( this . paramsFilter ? this . paramsFilter . getParam ( filter ) : null ) ?? true ) ; } } } } return true as any ; } }