From c8bf1900d8c472124921390cae66cc11fc9e7b19 Mon Sep 17 00:00:00 2001
From: L4168 <L4168@student.jamk.fi>
Date: Tue, 2 Jul 2019 10:03:53 +0300
Subject: [PATCH 01/10] added nestedvalidation centerJSON

---
 src/game/game.dto.ts | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/src/game/game.dto.ts b/src/game/game.dto.ts
index 09c39b7..4b1fa9b 100644
--- a/src/game/game.dto.ts
+++ b/src/game/game.dto.ts
@@ -7,11 +7,15 @@ import {
   Validate,
   Min,
   Max,
+  ValidateNested,
+  Allow,
 } from 'class-validator';
 
 import { ObjectivePointEntity } from './game.entity';
 import { CenterJSON } from '../shared/custom-validation';
 import { FactionDTO } from '../faction/faction.dto';
+import { CenterDTO } from './game.json.dto';
+import { Type } from 'class-transformer';
 
 export class GameDTO {
   @IsString()
@@ -22,9 +26,12 @@ export class GameDTO {
   @Length(1, 255)
   desc: string;
   @IsNotEmpty()
-  @Validate(CenterJSON)
-  center: JSON;
+  @ValidateNested()
+  @Type(() => CenterDTO)
+  center: CenterDTO;
+  @Allow()
   map?: JSON;
+  @Allow()
   nodesettings?: JSON;
   @IsDateString()
   @IsNotEmpty()
@@ -32,7 +39,9 @@ export class GameDTO {
   @IsDateString()
   @IsNotEmpty()
   enddate: string;
+  @Allow()
   factions?: FactionDTO[];
+  @Allow()
   objective_points?: FlagboxDTO[];
 }
 
-- 
GitLab


From 6c62d19a0dffa92f3f2d75f8d8b62de3c7e81410 Mon Sep 17 00:00:00 2001
From: L4168 <L4168@student.jamk.fi>
Date: Tue, 2 Jul 2019 10:04:35 +0300
Subject: [PATCH 02/10] center: CenterDTO

---
 src/game/game.entity.ts | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/game/game.entity.ts b/src/game/game.entity.ts
index b580665..030e81d 100644
--- a/src/game/game.entity.ts
+++ b/src/game/game.entity.ts
@@ -14,6 +14,7 @@ import { PersonEntity } from '../user/user.entity';
 import { GameGroupEntity } from '../faction/faction.entity';
 import { FactionEntity } from '../faction/faction.entity';
 import { TaskEntity } from '../task/task.entity';
+import { CenterDTO } from './game.json.dto';
 
 // table that stores all created games
 @Entity('Game')
@@ -21,7 +22,7 @@ export class GameEntity {
   @PrimaryGeneratedColumn('uuid') id: string;
   @Column('text') name: string;
   @Column('text') desc: string;
-  @Column('json') center: JSON;
+  @Column('json') center: CenterDTO;
   @Column({ type: 'json', nullable: true }) map: JSON;
   @Column({ type: 'json', nullable: true }) nodesettings?: JSON;
   @Column('timestamp') startdate: Timestamp;
-- 
GitLab


From 763d20b7b41b005b73fc1952cc12d2529f8380f2 Mon Sep 17 00:00:00 2001
From: L4168 <L4168@student.jamk.fi>
Date: Tue, 2 Jul 2019 10:04:52 +0300
Subject: [PATCH 03/10] subDTO for centerJSON

---
 src/game/game.json.dto.ts | 9 +++++++++
 1 file changed, 9 insertions(+)
 create mode 100644 src/game/game.json.dto.ts

diff --git a/src/game/game.json.dto.ts b/src/game/game.json.dto.ts
new file mode 100644
index 0000000..31bb481
--- /dev/null
+++ b/src/game/game.json.dto.ts
@@ -0,0 +1,9 @@
+import { GameDTO } from './game.dto';
+import { IsNumber } from 'class-validator';
+
+export class CenterDTO {
+  @IsNumber()
+  lat: number;
+  @IsNumber()
+  lng: number;
+}
-- 
GitLab


From 08f590520234f346a34644eabe865ef80fcc58e6 Mon Sep 17 00:00:00 2001
From: L4168 <L4168@student.jamk.fi>
Date: Tue, 2 Jul 2019 10:07:20 +0300
Subject: [PATCH 04/10] forbidNonWhitelisted: true

---
 src/shared/validation.pipe.ts | 81 ++++++++++++++++++++---------------
 1 file changed, 47 insertions(+), 34 deletions(-)

diff --git a/src/shared/validation.pipe.ts b/src/shared/validation.pipe.ts
index 27f078b..68eb4e8 100644
--- a/src/shared/validation.pipe.ts
+++ b/src/shared/validation.pipe.ts
@@ -1,44 +1,57 @@
-
-import { PipeTransform, Injectable, ArgumentMetadata, BadRequestException, HttpException, HttpStatus } from '@nestjs/common';
+import {
+  PipeTransform,
+  Injectable,
+  ArgumentMetadata,
+  HttpException,
+  HttpStatus,
+} from '@nestjs/common';
 import { validate } from 'class-validator';
 import { plainToClass } from 'class-transformer';
 
 @Injectable()
 export class ValidationPipe implements PipeTransform<any> {
-    async transform(value: any, metadata: ArgumentMetadata) {
-
-        if (value instanceof Object && this.isEmpty(value)) {
-            throw new HttpException(
-                'Validation failed: No body submitted', HttpStatus.BAD_REQUEST
-            );
-        }
-
-        const { metatype } = metadata;
-        if (!metatype || !this.toValidate(metatype)) {
-            return value;
-        }
-        const object = plainToClass(metatype, value);
-        const errors = await validate(object);
-        if (errors.length > 0) {
-            throw new HttpException(`Validation failed: ${this.formatErrors(errors)}`, HttpStatus.BAD_REQUEST);
-        }
-        return value;
+  async transform(value: any, metadata: ArgumentMetadata) {
+    if (value instanceof Object && this.isEmpty(value)) {
+      throw new HttpException(
+        'Validation failed: No body submitted',
+        HttpStatus.BAD_REQUEST,
+      );
     }
 
-    private toValidate(metatype: Function): boolean {
-        const types: Function[] = [String, Boolean, Number, Array, Object];
-        return !types.includes(metatype);
+    const { metatype } = metadata;
+    if (!metatype || !this.toValidate(metatype)) {
+      return value;
     }
-
-    private formatErrors(errors: any[]) {
-        return errors.map(err => {
-            for (let property in err.constraints) {
-                return err.constraints[property]
-            }
-        }).join(", ");
+    const object = plainToClass(metatype, value);
+    const errors = await validate(object, {
+      whitelist: true,
+      forbidNonWhitelisted: true,
+    });
+    if (errors.length > 0) {
+      throw new HttpException(
+        `Validation failed: ${this.formatErrors(errors)}`,
+        HttpStatus.BAD_REQUEST,
+      );
     }
+    return value;
+  }
 
-    private isEmpty(value: any) {
-        return (Object.keys(value).length > 0) ? false : true;
-    }
-}
\ No newline at end of file
+  private toValidate(metatype: Function): boolean {
+    const types: Function[] = [String, Boolean, Number, Array, Object];
+    return !types.includes(metatype);
+  }
+
+  private formatErrors(errors: any[]) {
+    return errors
+      .map(err => {
+        for (let property in err.constraints) {
+          return err.constraints[property];
+        }
+      })
+      .join(', ');
+  }
+
+  private isEmpty(value: any) {
+    return Object.keys(value).length > 0 ? false : true;
+  }
+}
-- 
GitLab


From 70993d76c6f7caac93a05a719603b00cf3f43fe8 Mon Sep 17 00:00:00 2001
From: L4168 <L4168@student.jamk.fi>
Date: Tue, 2 Jul 2019 17:08:25 +0300
Subject: [PATCH 05/10] json validation for node_settings

---
 src/game/game.dto.ts             |  9 +++++----
 src/game/game.entity.ts          |  4 ++--
 src/game/game.json-nested.dto.ts | 16 ++++++++++++++++
 src/game/game.json.dto.ts        | 11 +++++++++--
 4 files changed, 32 insertions(+), 8 deletions(-)
 create mode 100644 src/game/game.json-nested.dto.ts

diff --git a/src/game/game.dto.ts b/src/game/game.dto.ts
index 4b1fa9b..e4f12e3 100644
--- a/src/game/game.dto.ts
+++ b/src/game/game.dto.ts
@@ -14,7 +14,7 @@ import {
 import { ObjectivePointEntity } from './game.entity';
 import { CenterJSON } from '../shared/custom-validation';
 import { FactionDTO } from '../faction/faction.dto';
-import { CenterDTO } from './game.json.dto';
+import { CenterDTO, NodeSettingsDTO } from './game.json.dto';
 import { Type } from 'class-transformer';
 
 export class GameDTO {
@@ -25,14 +25,15 @@ export class GameDTO {
   @IsNotEmpty()
   @Length(1, 255)
   desc: string;
-  @IsNotEmpty()
   @ValidateNested()
   @Type(() => CenterDTO)
   center: CenterDTO;
   @Allow()
-  map?: JSON;
+  @ValidateNested()
+  @Type(() => NodeSettingsDTO)
+  nodesettings?: NodeSettingsDTO;
   @Allow()
-  nodesettings?: JSON;
+  map?: JSON;
   @IsDateString()
   @IsNotEmpty()
   startdate: string;
diff --git a/src/game/game.entity.ts b/src/game/game.entity.ts
index 030e81d..5f019e8 100644
--- a/src/game/game.entity.ts
+++ b/src/game/game.entity.ts
@@ -14,7 +14,7 @@ import { PersonEntity } from '../user/user.entity';
 import { GameGroupEntity } from '../faction/faction.entity';
 import { FactionEntity } from '../faction/faction.entity';
 import { TaskEntity } from '../task/task.entity';
-import { CenterDTO } from './game.json.dto';
+import { CenterDTO, NodeSettingsDTO } from './game.json.dto';
 
 // table that stores all created games
 @Entity('Game')
@@ -24,7 +24,7 @@ export class GameEntity {
   @Column('text') desc: string;
   @Column('json') center: CenterDTO;
   @Column({ type: 'json', nullable: true }) map: JSON;
-  @Column({ type: 'json', nullable: true }) nodesettings?: JSON;
+  @Column({ type: 'json', nullable: true }) nodesettings?: NodeSettingsDTO;
   @Column('timestamp') startdate: Timestamp;
   @Column('timestamp') enddate: Timestamp;
 
diff --git a/src/game/game.json-nested.dto.ts b/src/game/game.json-nested.dto.ts
new file mode 100644
index 0000000..df67071
--- /dev/null
+++ b/src/game/game.json-nested.dto.ts
@@ -0,0 +1,16 @@
+import { IsNumber } from 'class-validator';
+
+export class NodeCoreSettingsDTO {
+  @IsNumber()
+  capture_time: number;
+  @IsNumber()
+  confirmation_time: number;
+  @IsNumber()
+  owner: number;
+  @IsNumber()
+  capture: number;
+  @IsNumber()
+  buttons_available: number;
+  @IsNumber()
+  heartbeat_interval: number;
+}
diff --git a/src/game/game.json.dto.ts b/src/game/game.json.dto.ts
index 31bb481..5b9484a 100644
--- a/src/game/game.json.dto.ts
+++ b/src/game/game.json.dto.ts
@@ -1,5 +1,6 @@
-import { GameDTO } from './game.dto';
-import { IsNumber } from 'class-validator';
+import { IsNumber, ValidateNested } from 'class-validator';
+import { NodeCoreSettingsDTO } from './game.json-nested.dto';
+import { Type } from 'class-transformer';
 
 export class CenterDTO {
   @IsNumber()
@@ -7,3 +8,9 @@ export class CenterDTO {
   @IsNumber()
   lng: number;
 }
+
+export class NodeSettingsDTO {
+  @ValidateNested()
+  @Type(() => NodeCoreSettingsDTO)
+  node_settings: NodeCoreSettingsDTO;
+}
-- 
GitLab


From 54dd811e3308af7d167c9cb5d2a190db07f6142a Mon Sep 17 00:00:00 2001
From: Ronnie Friman <L4168@student.jamk.fi>
Date: Tue, 2 Jul 2019 19:22:13 +0300
Subject: [PATCH 06/10] added nested validation errors

---
 src/shared/validation.pipe.ts | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/src/shared/validation.pipe.ts b/src/shared/validation.pipe.ts
index 68eb4e8..cff51f1 100644
--- a/src/shared/validation.pipe.ts
+++ b/src/shared/validation.pipe.ts
@@ -7,6 +7,7 @@ import {
 } from '@nestjs/common';
 import { validate } from 'class-validator';
 import { plainToClass } from 'class-transformer';
+import { AdvancedConsoleLogger } from 'typeorm';
 
 @Injectable()
 export class ValidationPipe implements PipeTransform<any> {
@@ -44,13 +45,20 @@ export class ValidationPipe implements PipeTransform<any> {
   private formatErrors(errors: any[]) {
     return errors
       .map(err => {
-        for (let property in err.constraints) {
-          return err.constraints[property];
-        }
+        return this.returnError(err);
       })
       .join(', ');
   }
 
+  private returnError(err) {
+    if (err['children'] !== undefined && err['children'].length != 0) {
+      return this.formatErrors(err['children']);
+    }
+    for (let property in err.constraints) {
+      return err.constraints[property];
+    }
+  }
+
   private isEmpty(value: any) {
     return Object.keys(value).length > 0 ? false : true;
   }
-- 
GitLab


From 6dacd4ece0eb8908c0651a57d717762a66320fa8 Mon Sep 17 00:00:00 2001
From: Ronnie Friman <L4168@student.jamk.fi>
Date: Tue, 2 Jul 2019 19:22:53 +0300
Subject: [PATCH 07/10] added json validation for editgame factions

---
 src/faction/faction.dto.ts | 11 ++++++++++-
 src/game/game.dto.ts       |  3 ++-
 2 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/src/faction/faction.dto.ts b/src/faction/faction.dto.ts
index 1db90ce..a5b9f04 100644
--- a/src/faction/faction.dto.ts
+++ b/src/faction/faction.dto.ts
@@ -4,6 +4,9 @@ import {
   Validate,
   IsString,
   IsNotEmpty,
+  IsNumber,
+  Min,
+  Max,
 } from 'class-validator';
 
 import { GameEntity } from '../game/game.entity';
@@ -14,9 +17,15 @@ import { FactionEntity, GameGroupEntity } from './faction.entity';
 export class FactionDTO {
   @IsString()
   @IsNotEmpty()
-  @Length(2, 15)
+  @Length(2, 31)
   factionName: string;
+  @IsString()
+  @IsNotEmpty()
+  @Length(3, 15)
   factionPassword: string;
+  @IsNumber()
+  @Min(1)
+  @Max(3)
   multiplier?: number;
   game: GameDTO;
 }
diff --git a/src/game/game.dto.ts b/src/game/game.dto.ts
index e4f12e3..5549aa0 100644
--- a/src/game/game.dto.ts
+++ b/src/game/game.dto.ts
@@ -40,7 +40,8 @@ export class GameDTO {
   @IsDateString()
   @IsNotEmpty()
   enddate: string;
-  @Allow()
+  @ValidateNested()
+  @Type(() => FactionDTO)
   factions?: FactionDTO[];
   @Allow()
   objective_points?: FlagboxDTO[];
-- 
GitLab


From 511334e49ba415581243dcd494726f84bac8e1d4 Mon Sep 17 00:00:00 2001
From: Ronnie Friman <L4168@student.jamk.fi>
Date: Tue, 2 Jul 2019 19:24:55 +0300
Subject: [PATCH 08/10] added json validation for editgame flagboxes

---
 src/game/game.dto.ts | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/game/game.dto.ts b/src/game/game.dto.ts
index 5549aa0..913b6c0 100644
--- a/src/game/game.dto.ts
+++ b/src/game/game.dto.ts
@@ -43,7 +43,8 @@ export class GameDTO {
   @ValidateNested()
   @Type(() => FactionDTO)
   factions?: FactionDTO[];
-  @Allow()
+  @ValidateNested()
+  @Type(() => FlagboxDTO)
   objective_points?: FlagboxDTO[];
 }
 
-- 
GitLab


From a78ac42689cdd0a7ec43394dec70cb818b34ddcb Mon Sep 17 00:00:00 2001
From: L4168 <L4168@student.jamk.fi>
Date: Wed, 3 Jul 2019 09:45:56 +0300
Subject: [PATCH 09/10] added listFactions for gm

---
 src/game/game.controller.ts | 7 +++++++
 src/game/game.service.ts    | 4 ++++
 2 files changed, 11 insertions(+)

diff --git a/src/game/game.controller.ts b/src/game/game.controller.ts
index a97155c..015baf9 100644
--- a/src/game/game.controller.ts
+++ b/src/game/game.controller.ts
@@ -17,6 +17,7 @@ import { User } from '../user/user.decorator';
 import { GameDTO, FlagboxEventDTO } from './game.dto';
 import { ValidationPipe } from '../shared/validation.pipe';
 import { Roles } from '../shared/roles.decorator';
+import { GameEntity } from './game.entity';
 
 @Controller('game')
 export class GameController {
@@ -48,6 +49,12 @@ export class GameController {
     return this.gameservice.returnGameInfo(id);
   }
 
+  @Get('get-factions/:id')
+  @Roles('admin')
+  async returnGameFactions(@Param('id') id: GameEntity) {
+    return this.gameservice.listFactions(id);
+  }
+
   @Get('flag/:id')
   async flagboxQuery(@Param('id') id: string) {
     return this.gameservice.flagboxQuery(id);
diff --git a/src/game/game.service.ts b/src/game/game.service.ts
index 9a74a46..37f2e47 100644
--- a/src/game/game.service.ts
+++ b/src/game/game.service.ts
@@ -110,6 +110,10 @@ export class GameService {
     };
   }
 
+  async listFactions(game: GameEntity) {
+    return this.factionRepository.find({ game });
+  }
+
   async deleteGame(id) {
     // TODO: Delete factions from Faction table associated with the deleted game
     await this.gameRepository.delete({ id });
-- 
GitLab


From c3a2e613304003b08b703a21e7905f10faa07a9b Mon Sep 17 00:00:00 2001
From: L4168 <L4168@student.jamk.fi>
Date: Wed, 3 Jul 2019 12:48:05 +0300
Subject: [PATCH 10/10] added response codes

---
 src/faction/faction.service.ts | 2 ++
 src/game/game.service.ts       | 7 +++++++
 2 files changed, 9 insertions(+)

diff --git a/src/faction/faction.service.ts b/src/faction/faction.service.ts
index 4402878..76242df 100644
--- a/src/faction/faction.service.ts
+++ b/src/faction/faction.service.ts
@@ -94,6 +94,7 @@ export class FactionService {
     await this.game_PersonRepository.save(gamePerson);
 
     return {
+      code: 201,
       message: 'created new group',
     };
   }
@@ -113,6 +114,7 @@ export class FactionService {
     gamePerson.group = data.groupId;
     await this.game_PersonRepository.save(gamePerson);
     return {
+      code: 200,
       message: 'Joined group',
     };
   }
diff --git a/src/game/game.service.ts b/src/game/game.service.ts
index 37f2e47..573bb22 100644
--- a/src/game/game.service.ts
+++ b/src/game/game.service.ts
@@ -48,6 +48,7 @@ export class GameService {
     });
     await this.game_PersonRepository.insert(gamePerson);
     return {
+      code: 201,
       message: 'New game added',
     };
   }
@@ -106,6 +107,7 @@ export class GameService {
     // TO DO: ADD FLAGBOX LOCATION TO MAPDRAWING ENTITY
 
     return {
+      code: 200,
       message: 'Game updated',
     };
   }
@@ -118,6 +120,7 @@ export class GameService {
     // TODO: Delete factions from Faction table associated with the deleted game
     await this.gameRepository.delete({ id });
     return {
+      code: 200,
       message: 'Game deleted',
     };
   }
@@ -168,5 +171,9 @@ export class GameService {
     await this.objectivePoint_HistoryRepository.insert(eventUpdate);
     // send flagbox event to flagbox subscribers
     this.notificationGateway.server.emit('flagbox', 'event update');
+    return {
+      code: 201,
+      message: 'OK',
+    };
   }
 }
-- 
GitLab