I have a controller with a route that I want to protect with Guards. I have these three gards: IsAuthentifiedGuard, HasRoleGuard and IsSafeGuard and I want at least one of these two conditions to be valid:
- IsAuthentifiedGuard and HasRoleGuard are OK
- IsSafeGuard is OK
For example, if the user is authentified AND has an enough role, it should be OK but if not but the call is "safe" I also want it to be OK.
My OrGuard:
@Injectable()
export class OrGuard implements CanActivate {
constructor(private readonly orGuards: CanActivate[][]) {}
async canActivate(context: ExecutionContext): Promise<boolean> {
const orGuardsPromises = await Promise.all(
this.orGuards.map(async andGuards => {
const andGuardPromises = await Promise.all(
andGuards.map(async guard => {
return guard.canActivate(context)
}),
)
return andGuardPromises.every(canActivate => canActivate === true)
}),
)
return orGuardsPromises.some(canActivate => canActivate === true)
}
}
And my controller:
@Controller('my_route')
export class MyController {
@Post('/')
@UseGuards(new OrGuard([[new IsAuthentifiedGuard(), new HasRoleGuard()], [new IsSafeGuard()]]))
async myRoute() {}
}
But I've a problem with the guards that require dependencies. For example if HasRoleGuard requires a ConfigService in constructor, this doesn't work.
An other way would be to use my or guard as following:
@UseGuards(OrGuard)
@SetMetadata('orGuards', [[IsAuthentifiedGuard, HasRoleGuard], [IsSafeGuard]])
But in my guard, I don't succeed to instanciate these guards from their class name with all the dependencies they need.
What can you suggest?