diff --git a/src/shared/states.guard.ts b/src/shared/states.guard.ts new file mode 100644 index 0000000000000000000000000000000000000000..fb8a18fbb51b5f265d567ba5c62e2039a6d83e1a --- /dev/null +++ b/src/shared/states.guard.ts @@ -0,0 +1,46 @@ +import { + Injectable, + CanActivate, + ExecutionContext, + HttpException, + HttpStatus, +} from '@nestjs/common'; +import { Reflector } from '@nestjs/core'; +import { InjectRepository } from '@nestjs/typeorm'; +import { Repository } from 'typeorm'; + +import { GameEntity } from '../game/game.entity'; + +@Injectable() +export class StatesGuard implements CanActivate { + constructor( + private readonly reflector: Reflector, + @InjectRepository(GameEntity) + private gameRepository: Repository<GameEntity>, + ) {} + + async canActivate(context: ExecutionContext): Promise<boolean> { + // get game states that are allowed access, identified by @GameStates('state') decorators in controllers + const states = this.reflector.get<string[]>('states', context.getHandler()); + console.log(states); + if (!states) { + return true; + } + const request = context.switchToHttp().getRequest(); + const gameId = request.params.id; + const gameRef = await this.gameRepository.findOne({ + id: gameId, + }); + // check that the gameState matches the criteria + if (gameRef && states.includes(gameRef.state)) { + return true; + } else { + throw new HttpException( + `Game is set to ${ + gameRef.state + }, operation only valid in states ${states.join(', ')}`, + HttpStatus.BAD_REQUEST, + ); + } + } +}