import { BaseEntity , JoinTable , ManyToMany , PrimaryGeneratedColumn } from 'typeorm' ; import { Group } from './group.entity' ; import { Permission } from './permission.entity' ; export abstract class export abstract class UserWithPermissions extends BaseEntity { static template T param { string } codeName returns { Promise < T [ ] > } memberof static async withPerm < T extends UserWithPermissions > ( codeName ) { const userWithUserPermissionsQb = this . createQueryBuilder ( 'user1' ) . select ( 'user1.id' ) . innerJoin ( 'user1.userPermissions' , 'userPermission' ) . where ( 'userPermission.codeName = :codeName' ) ; const userWithGroupPermissionsQb = this . createQueryBuilder ( 'user2' ) . select ( 'user2.id' ) . innerJoin ( 'user2.groups' , 'group' ) . innerJoin ( 'group.permissions' , 'groupPermission' ) . where ( 'groupPermission.codeName = :codeName' ) ; return await this . createQueryBuilder ( 'user' ) . where ( 'user.id IN (' + userWithUserPermissionsQb . getQuery ( ) + ')' ) . orWhere ( 'user.id IN (' + userWithGroupPermissionsQb . getQuery ( ) + ')' ) . setParameters ( { codeName } ) . getMany ( ) as T [ ] ; } @ PrimaryGeneratedColumn ( ) id : number ; @ ManyToMany ( type => Group ) @ JoinTable ( ) groups : Group [ ] ; @ ManyToMany ( type => Permission ) @ JoinTable ( ) userPermissions : Permission [ ] ; param { string } codeName returns { boolean } memberof hasPerm ( codeName ) { for ( const permission of this . userPermissions || [ ] ) { if ( permission . codeName === codeName ) { return true ; } } for ( const group of this . groups || [ ] ) { for ( const permission of group . permissions || [ ] ) { if ( permission . codeName === codeName ) { return true ; } } } return false ; } }