diff --git a/ormconfig.json b/ormconfig.json index bb6b5fae1ce31ce82b0b7c85dda0cfc2a604bba9..2e271682f33485978ad86f39916a4d795b39e310 100644 --- a/ormconfig.json +++ b/ormconfig.json @@ -1,10 +1,10 @@ { "type": "postgres", "host": "localhost", - "port": 5432, - "username": "ehasa", - "password": "salasana", - "database": "ehasa", + "port": 5444, + "username": "postgres", + "password": "mysecretpassword", + "database": "test", "entities": ["src/**/*.entity{.ts,.js}"], "synchronize": true, "logging": true, diff --git a/package-lock.json b/package-lock.json index 53a606c27128a913a5a331e85d089988f9f164f0..fd2af0db0f3c47f7a96abd6b2847f5b6f33900a3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1450,11 +1450,6 @@ "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.5.tgz", "integrity": "sha512-gaqbzQPqOoamawKg0LGVd7SzLgXS+JH61oWprSLH+P+abTczqJbhTR8CmJ2u9/bUYNmHTGJx/UEmn6doAvvuig==" }, - "bluebird": { - "version": "3.5.5", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.5.tgz", - "integrity": "sha512-5am6HnnfN+urzt4yfg7IgTbotDjIT/u8AJpEt0sIU9FtXfVeezXAPKswrG+xKUCOYAINpSdgZVDU6QFh+cuH3w==" - }, "body-parser": { "version": "1.19.0", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", @@ -1906,15 +1901,6 @@ "wrap-ansi": "^2.0.0" } }, - "cls-bluebird": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cls-bluebird/-/cls-bluebird-2.1.0.tgz", - "integrity": "sha1-N+8eCAqP+1XC9BZPU28ZGeeWiu4=", - "requires": { - "is-bluebird": "^1.0.2", - "shimmer": "^1.1.0" - } - }, "co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", @@ -2397,11 +2383,6 @@ "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-6.2.0.tgz", "integrity": "sha512-HygQCKUBSFl8wKQZBSemMywRWcEDNidvNbjGVyZu3nbZ8qq9ubiPoGLMdRDpfSrpkkm9BXYFkpKxxFX38o/76w==" }, - "dottie": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/dottie/-/dottie-2.0.1.tgz", - "integrity": "sha512-ch5OQgvGDK2u8pSZeSYAQaV/lczImd7pMJ7BcEPXmnFVjy4yJIzP6CsODJUTH8mg1tyH1Z2abOiuJO3DjZ/GBw==" - }, "double-ended-queue": { "version": "2.1.0-0", "resolved": "https://registry.npmjs.org/double-ended-queue/-/double-ended-queue-2.1.0-0.tgz", @@ -4020,11 +4001,6 @@ "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=" }, - "inflection": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/inflection/-/inflection-1.12.0.tgz", - "integrity": "sha1-ogCTVlbW9fa8TcdQLhrstwMihBY=" - }, "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -4088,11 +4064,6 @@ "binary-extensions": "^1.0.0" } }, - "is-bluebird": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-bluebird/-/is-bluebird-1.0.2.tgz", - "integrity": "sha1-CWQ5Bg9KpBGr7hkUOoTWpVNG1uI=" - }, "is-buffer": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", @@ -5145,7 +5116,8 @@ "lodash": { "version": "4.17.11", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", - "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==" + "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==", + "dev": true }, "lodash.includes": { "version": "4.3.0", @@ -5443,19 +5415,6 @@ "minimist": "0.0.8" } }, - "moment": { - "version": "2.24.0", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz", - "integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==" - }, - "moment-timezone": { - "version": "0.5.25", - "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.25.tgz", - "integrity": "sha512-DgEaTyN/z0HFaVcVbSyVCUU6HeFdnNC3vE4c9cgu2dgMTvjBUBdBzWfasTBmAW45u5OIMeCJtU8yNjM22DHucw==", - "requires": { - "moment": ">= 2.9.0" - } - }, "ms": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", @@ -6553,14 +6512,6 @@ "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", "dev": true }, - "retry-as-promised": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/retry-as-promised/-/retry-as-promised-3.2.0.tgz", - "integrity": "sha512-CybGs60B7oYU/qSQ6kuaFmRd9sTZ6oXSc0toqePvV74Ac6/IFZSI1ReFQmtCN+uvW1Mtqdwpvt/LGOiCBAY2Mg==", - "requires": { - "any-promise": "^1.3.0" - } - }, "rimraf": { "version": "2.6.3", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", @@ -6689,51 +6640,6 @@ } } }, - "sequelize": { - "version": "5.8.7", - "resolved": "https://registry.npmjs.org/sequelize/-/sequelize-5.8.7.tgz", - "integrity": "sha512-1rubZM8fAyCt5ipyS+3HJ3Jbmb8WesLdPJ3jIbTD+78EbuPZILFEA5fK0mliVRBx7oM7oPULeVX0lxSRXBV1jw==", - "requires": { - "bluebird": "^3.5.0", - "cls-bluebird": "^2.1.0", - "debug": "^4.1.1", - "dottie": "^2.0.0", - "inflection": "1.12.0", - "lodash": "^4.17.11", - "moment": "^2.24.0", - "moment-timezone": "^0.5.21", - "retry-as-promised": "^3.1.0", - "semver": "^5.6.0", - "sequelize-pool": "^1.0.2", - "toposort-class": "^1.0.1", - "uuid": "^3.2.1", - "validator": "^10.11.0", - "wkx": "^0.4.6" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "requires": { - "ms": "^2.1.1" - } - }, - "validator": { - "version": "10.11.0", - "resolved": "https://registry.npmjs.org/validator/-/validator-10.11.0.tgz", - "integrity": "sha512-X/p3UZerAIsbBfN/IwahhYaBbY68EN/UQBWHtsbXGT5bfrH/p4NQzUCG1kF/rtKaNpnJ7jAu6NGTdSNtyNIXMw==" - } - } - }, - "sequelize-pool": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/sequelize-pool/-/sequelize-pool-1.0.2.tgz", - "integrity": "sha512-VMKl/gCCdIvB1gFZ7p+oqLFEyZEz3oMMYjkKvfEC7GoO9bBcxmfOOU9RdkoltfXGgBZFigSChihRly2gKtsh2w==", - "requires": { - "bluebird": "^3.5.3" - } - }, "serve-static": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", @@ -6797,11 +6703,6 @@ "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==", "dev": true }, - "shimmer": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/shimmer/-/shimmer-1.2.1.tgz", - "integrity": "sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==" - }, "signal-exit": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", @@ -7555,11 +7456,6 @@ } } }, - "toposort-class": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toposort-class/-/toposort-class-1.0.1.tgz", - "integrity": "sha1-f/0feMi+KMO6Rc1OGj9e4ZO9mYg=" - }, "touch": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", @@ -8256,14 +8152,6 @@ "string-width": "^2.1.1" } }, - "wkx": { - "version": "0.4.6", - "resolved": "https://registry.npmjs.org/wkx/-/wkx-0.4.6.tgz", - "integrity": "sha512-LHxXlzRCYQXA9ZHgs8r7Gafh0gVOE8o3QmudM1PIkOdkXXjW7Thcl+gb2P2dRuKgW8cqkitCRZkkjtmWzpHi7A==", - "requires": { - "@types/node": "*" - } - }, "wordwrap": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", diff --git a/src/draw/draw.controller.ts b/src/draw/draw.controller.ts index b271409d1b553cb9806cd8b706ee62f3e1958691..19b9d271c0d51aea80deebbbf353d899b3c3c0a7 100644 --- a/src/draw/draw.controller.ts +++ b/src/draw/draw.controller.ts @@ -7,14 +7,17 @@ import { UsePipes, ValidationPipe, Body, + Delete, } from '@nestjs/common'; import { AuthGuard } from 'src/shared/auth.guard'; import { DrawService } from './draw.service'; -import { MapDrawingDTO } from './mapdrawing.dto'; +import { MapDrawingDTO, DrawMapDTO } from './mapdrawing.dto'; import { Roles } from 'src/shared/roles.decorator'; import { User } from 'src/user/user.decorator'; import { FactionDTO } from 'src/game/game.dto'; import { FactionEntity } from 'src/game/faction.entity'; +import { async } from 'rxjs/internal/scheduler/async'; +import { Game_PersonEntity } from 'src/game/game.entity'; /* DrawController @@ -26,25 +29,22 @@ import { FactionEntity } from 'src/game/faction.entity'; export class DrawController { constructor(private drawService: DrawService) {} - @Put() - @UseGuards(new AuthGuard()) + @Put('mapdrawing/:id') @UsePipes(new ValidationPipe()) - async draw(@Body() data: MapDrawingDTO) { - try { - return this.drawService.draw(data); - } catch (error) { - return error.message; - } + @Roles('admin', 'factionleader') + async draw(@Param('id') gameId, @Body() data) { + return this.drawService.draw(gameId, data); } - @Get(':id') + @Get('map/:id') @UseGuards(new AuthGuard()) @UsePipes(new ValidationPipe()) - async drawMap(@Param('id') id: string, @Body() faction: FactionDTO) { - try { - return this.drawService.drawMap(id, faction); - } catch (error) { - return error.message; - } + async drawMap(@Param('id') id, @Body() data) { + return this.drawService.drawMap(id, data); } + + @Put('location') + @UseGuards(new AuthGuard()) + @UsePipes(new ValidationPipe()) + async trackLocation() {} } diff --git a/src/draw/draw.module.ts b/src/draw/draw.module.ts index 34390bfefbdfc55285ffd6e809126878562bbb12..7f4ef3ad3496b1b3a9ebb5872c2f43108cbe2732 100644 --- a/src/draw/draw.module.ts +++ b/src/draw/draw.module.ts @@ -5,12 +5,19 @@ import { DrawController } from './draw.controller'; import { DrawService } from './draw.service'; import { MapDrawingEntity } from 'src/game/coordinate.entity'; import { FactionEntity } from 'src/game/faction.entity'; +import { Game_PersonEntity } from 'src/game/game.entity'; /* Draw - contains everything to do with mapdrawing data. */ @Module({ - imports: [TypeOrmModule.forFeature([MapDrawingEntity, FactionEntity])], + imports: [ + TypeOrmModule.forFeature([ + MapDrawingEntity, + FactionEntity, + Game_PersonEntity, + ]), + ], controllers: [DrawController], providers: [DrawService], }) diff --git a/src/draw/draw.service.ts b/src/draw/draw.service.ts index f00c48d10b6437f5a1c3e3936254ac02949a670b..2d983c51f555752dfbd1ae2c7bf63a8a20a81270 100644 --- a/src/draw/draw.service.ts +++ b/src/draw/draw.service.ts @@ -2,7 +2,7 @@ import { Injectable } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; import { MapDrawingEntity } from 'src/game/coordinate.entity'; import { Repository } from 'typeorm'; -import { MapDrawingDTO } from './mapdrawing.dto'; +import { MapDrawingDTO, DrawMapDTO } from './mapdrawing.dto'; import { Game_PersonEntity, GameEntity } from '../game/game.entity'; import { GameDTO, FactionDTO } from 'src/game/game.dto'; import { FactionEntity } from 'src/game/faction.entity'; @@ -14,30 +14,35 @@ export class DrawService { private mapDrawingRepository: Repository<MapDrawingEntity>, @InjectRepository(FactionEntity) private factionRepository: Repository<FactionEntity>, + @InjectRepository(Game_PersonEntity) + private game_personRepository: Repository<Game_PersonEntity>, ) {} - async draw(data: MapDrawingDTO) { - try { - return this.mapDrawingRepository.insert(data); - } catch (error) { - return error; + async draw(gameId, data: MapDrawingEntity) { + data['gameId'] = gameId; + const drawing = await this.mapDrawingRepository.create(data); + + if (data.mapDrawingId == null || data.mapDrawingId == '') { + // luo uuden instanssin. + return this.mapDrawingRepository.insert(drawing)[0]; + } else { + //päivittää mapDrawingin + return await this.mapDrawingRepository.save(drawing); } } // draw map based on game and - async drawMap(id: string, faction: FactionDTO) { - try { - // get faction - const factionInDb = await this.factionRepository.findOne({ - where: { game: id, factionName: faction.factionName }, - }); + async drawMap(id, data: MapDrawingEntity) { + data['gameId'] = id; + data['drawingIsActive'] = true; + // get faction + const mapDrawings = await this.mapDrawingRepository.create(data); - // return mapdrawings with given faction and gameid - return this.mapDrawingRepository.find({ - where: { gameId: id, faction: factionInDb }, - }); - } catch (error) { - return error; - } + // return mapdrawings with given faction and gameid + return await this.mapDrawingRepository.find(mapDrawings); } + + // async trackLocation() { + // return 'location'; + // } } diff --git a/src/draw/mapdrawing.dto.ts b/src/draw/mapdrawing.dto.ts index f51937de0f8eb90e93869d9f3ef098c2ab84e993..0e559fa052c8873cdfdfcfecfa325cfe6de0f5dd 100644 --- a/src/draw/mapdrawing.dto.ts +++ b/src/draw/mapdrawing.dto.ts @@ -1,4 +1,8 @@ import { GameDTO, FactionDTO } from '../game/game.dto'; +import { GameEntity, Game_PersonEntity } from 'src/game/game.entity'; +import { FactionEntity } from 'src/game/faction.entity'; +import { MapDrawingEntity } from 'src/game/coordinate.entity'; +import { IsUUID } from 'class-validator'; export class MapDrawingDTO { data: JSON; @@ -7,3 +11,14 @@ export class MapDrawingDTO { isActive?: boolean; validUntil?: string; } + +export class DrawMapDTO { + @IsUUID('4') + mapDrawingId: MapDrawingEntity; + + gameId: GameEntity; + factionId: FactionEntity; + + gamepersonId: Game_PersonEntity; + data: JSON; +} diff --git a/src/game/game.controller.ts b/src/game/game.controller.ts index 363bcbda70113b092f2fb9273ca65a0dda7129ae..bd6551ad714d9abbe172ef2a9be0d9301d8d79a6 100644 --- a/src/game/game.controller.ts +++ b/src/game/game.controller.ts @@ -12,7 +12,13 @@ import { import { GameService } from './game.service'; import { AuthGuard } from '../shared/auth.guard'; import { User } from '../user/user.decorator'; -import { GameDTO, GameGroupDTO, FlagboxEventDTO } from './game.dto'; +import { + GameDTO, + GameGroupDTO, + FlagboxEventDTO, + JoinFactionDTO, + PromotePlayerDTO, +} from './game.dto'; import { ValidationPipe } from '../shared/validation.pipe'; import { Roles } from '../shared/roles.decorator'; @@ -61,15 +67,17 @@ export class GameController { // param game ID is passed to @Roles @Put('promote/:id') @UseGuards(new AuthGuard()) + @UsePipes(new ValidationPipe()) @Roles('admin') - promotePlayer(@Param('id') game, @Body() body) { + promotePlayer(@Param('id') game, @Body() body: PromotePlayerDTO) { return this.gameservice.promotePlayer(body); } @Put('join-faction') @UseGuards(new AuthGuard()) - joinFaction(@User('id') person, @Body() faction) { - return this.gameservice.joinFaction(person, faction); + @UsePipes(new ValidationPipe()) + joinFaction(@User('id') person, @Body() data: JoinFactionDTO) { + return this.gameservice.joinFaction(person, data); } @Get('listgames') diff --git a/src/game/game.dto.ts b/src/game/game.dto.ts index aa0bc49851e117567637aeaeb035caa93234e657..df93b55b574ce8590c728a82f14f928a3b16a6d4 100644 --- a/src/game/game.dto.ts +++ b/src/game/game.dto.ts @@ -10,9 +10,13 @@ import { IsJSON, IsDateString, IsNumber, + IsUUID, + Validate, } from 'class-validator'; import { Timestamp } from 'typeorm'; -import { ObjectivePointEntity } from './game.entity'; +import { ObjectivePointEntity, GameEntity } from './game.entity'; +import { StringifyOptions } from 'querystring'; +import { Uuid, RoleValidation } from '../shared/custom-validation'; export class GameDTO { @IsString() @@ -75,3 +79,19 @@ export class GameGroupDTO { @Length(3, 31) name: string; } + +export class JoinFactionDTO { + @IsUUID('4') + factionId: string; + @Length(3, 31) + factionPassword: string; + @IsUUID('4') + game: GameEntity; +} + +export class PromotePlayerDTO { + @IsUUID('4') + player: string; + @Validate(RoleValidation) + role: string; +} diff --git a/src/game/game.service.ts b/src/game/game.service.ts index dc1d92982afc59066f31f16e3153e7361e75aead..571075290d777049db0a90e80a28b62e0f55e102 100644 --- a/src/game/game.service.ts +++ b/src/game/game.service.ts @@ -8,7 +8,7 @@ import { ObjectivePointEntity, ObjectivePoint_HistoryEntity, } from './game.entity'; -import { GameDTO, FlagboxEventDTO } from './game.dto'; +import { GameDTO, FlagboxEventDTO, JoinFactionDTO } from './game.dto'; import { PersonEntity } from '../user/user.entity'; import { GameGroupEntity } from './group.entity'; import { FactionEntity } from './faction.entity'; @@ -249,19 +249,19 @@ export class GameService { throw new HttpException('player does not exist', HttpStatus.BAD_REQUEST); } - async joinFaction(person, faction) { - const name = faction.factionName; + async joinFaction(person, faction: JoinFactionDTO) { // get faction const factionInDb = await this.factionRepository.findOne({ - where: { name }, + factionId: faction.factionId, }); + if (!factionInDb) { throw new HttpException('No factions exist!', HttpStatus.BAD_REQUEST); } //check if password is correct if (factionInDb.passwordCheck(faction.factionPassword)) { const gameperson = await this.game_PersonRepository.create({ - faction: faction.factionName, + faction: factionInDb, game: faction.game, role: 'soldier', person: person, diff --git a/src/shared/custom-validation.ts b/src/shared/custom-validation.ts new file mode 100644 index 0000000000000000000000000000000000000000..a920e717e08a6981f5f2e82ddc5cf237ecddba11 --- /dev/null +++ b/src/shared/custom-validation.ts @@ -0,0 +1,32 @@ +import { + ValidatorConstraint, + ValidatorConstraintInterface, + ValidationArguments, + Validator, +} from 'class-validator'; + +// check if input is null or valid uuid +@ValidatorConstraint({ name: 'uuid', async: true }) +export class Uuid implements ValidatorConstraintInterface { + validate(uuid: string, args: ValidationArguments) { + const validator = new Validator(); + return validator.isUUID(uuid, '4') || uuid == null; // for async validations you must return a Promise<boolean> here + } + + defaultMessage(args: ValidationArguments) { + return 'Not valid uuid'; + } +} + +// checks if role is valid +@ValidatorConstraint({ name: 'roleValidation', async: true }) +export class RoleValidation implements ValidatorConstraintInterface { + validate(role: string, args: ValidationArguments) { + const validRoles = ['admin', 'soldier', 'factionleader']; + return validRoles.includes(role); + } + + defaultMessage(args: ValidationArguments) { + return 'Not valid uuid'; + } +}