diff --git a/src/canvas/canvas.controller.ts b/src/canvas/canvas.controller.ts index ea5fc7a..56ba7b9 100644 --- a/src/canvas/canvas.controller.ts +++ b/src/canvas/canvas.controller.ts @@ -12,7 +12,7 @@ import { } from '@nestjs/common'; import { CanvasService } from './canvas.service'; import { - CanvasAccessByTagDTO, + GiveCanvasAccessByTagDTO, CanvasAccessDTO, CanvasContentUpdateDto, CanvasCreateDTO, @@ -20,6 +20,7 @@ import { CanvasMetadataUpdateDTO, CanvasModifyTagDTO, CanvasStateFilter, + CancelCanvasAccessByTagDTO, } from './canvas.interface'; import { Uuid } from '../common/common.interface'; import { ListFilter, PagedResult } from '../common/pageable.utils'; @@ -251,7 +252,7 @@ export class CanvasController { /** * Gives access to a single canvas for a single user * @param canvasId - * @param dto - an object containing 'userId' + * @param dto - an object containing 'personId' */ @Post('/:id/access') @UseGuards(AuthenticatedGuard, CanvasGuard) @@ -259,29 +260,38 @@ export class CanvasController { @Param('id') canvasId: Uuid, @Body() dto: CanvasAccessDTO, ) { - const userId = dto.userId; - await this.canvasService.giveAccess({ canvasId, userId }); + await this.canvasService.giveAccess({ canvasId, ...dto }); } /** * Removes access to a single canvas for a single user * @param canvasId - * @param dto - an object containing 'userId' + * @param dto - an object containing 'personId' + * @param req - HTTP request object */ @Delete('/:id/access') @UseGuards(AuthenticatedGuard, CanvasGuard) public async cancelAccess( @Param('id') canvasId: Uuid, @Body() dto: CanvasAccessDTO, + @Req() req: Request, ) { - const userId = dto.userId; - await this.canvasService.cancelAccess({ canvasId, userId }); + await this.canvasService.cancelAccess({ + userId: req.user.toString(), + canvasId, + ...dto, + }); } + /** + * Gives access to canvases with tags from the given list for selected users + * @param dto - an object containing 'tagIds' & 'personIds' + * @param req - HTTP request object + */ @Post('/access') @UseGuards(AuthenticatedGuard) public async giveAccessByTag( - @Body() dto: CanvasAccessByTagDTO, + @Body() dto: GiveCanvasAccessByTagDTO, @Req() req: Request, ) { await this.canvasService.giveAccessByTag({ @@ -291,9 +301,26 @@ export class CanvasController { } /** - * Adds a single tag to a canvas + * Removes access to canvases with tags from the given list + * @param dto - an object containing 'tagIds' + * @param req - HTTP request object + */ + @Delete('/access') + @UseGuards(AuthenticatedGuard) + public async cancelAccessByTag( + @Body() dto: CancelCanvasAccessByTagDTO, + @Req() req: Request, + ) { + await this.canvasService.cancelAccessByTag({ + userId: req.user.toString(), + ...dto, + }); + } + + /** + * Adds tags to a canvas * @param canvasId - * @param dto - an object containing 'tagId' + * @param dto - an object containing 'tagIds' */ @Post('/:id/tags') @UseGuards(AuthenticatedGuard, CanvasGuard) @@ -306,9 +333,9 @@ export class CanvasController { } /** - * Removes a single tag from a canvas + * Removes tags from a canvas * @param canvasId - * @param dto - an object containing 'tagId' + * @param dto - an object containing 'tagIds' */ @Delete('/:id/tags') @UseGuards(AuthenticatedGuard, CanvasGuard) diff --git a/src/canvas/canvas.interface.ts b/src/canvas/canvas.interface.ts index 2585b74..7f36809 100644 --- a/src/canvas/canvas.interface.ts +++ b/src/canvas/canvas.interface.ts @@ -31,12 +31,13 @@ export interface CanvasMetadataUpdateCommand { export interface GiveAccessCommand { canvasId: Uuid; - userId: Uuid; + personId: Uuid; } export interface CancelAccessCommand { - canvasId: Uuid; userId: Uuid; + canvasId: Uuid; + personId: Uuid; } export interface GiveAccessByTagCommand { @@ -45,6 +46,11 @@ export interface GiveAccessByTagCommand { personIds: Uuid[]; } +export interface CancelAccessByTagCommand { + userId: Uuid; + tagIds: Uuid[]; +} + export interface CanvasAddTagCommand { canvasId: Uuid; tagIds: Uuid[]; @@ -90,10 +96,10 @@ export interface CanvasTagDTO { export class CanvasAccessDTO { @IsUUID() @IsNotEmpty() - userId: Uuid; + personId: Uuid; } -export class CanvasAccessByTagDTO { +export class GiveCanvasAccessByTagDTO { @IsUUID('all', { each: true }) @IsNotEmpty({ each: true }) @IsNotEmpty() @@ -104,6 +110,13 @@ export class CanvasAccessByTagDTO { personIds: Uuid[]; } +export class CancelCanvasAccessByTagDTO { + @IsUUID('all', { each: true }) + @IsNotEmpty({ each: true }) + @IsNotEmpty() + tagIds: Uuid[]; +} + export class CanvasStateFilter { @IsOptional() versionTimestamp?: string; diff --git a/src/canvas/canvas.service.ts b/src/canvas/canvas.service.ts index 75350fe..5711ff6 100644 --- a/src/canvas/canvas.service.ts +++ b/src/canvas/canvas.service.ts @@ -3,6 +3,7 @@ import { Repository } from 'typeorm'; import { CanvasEntity } from './entity/canvas.entity'; import { InjectRepository } from '@nestjs/typeorm'; import { + CancelAccessByTagCommand, CancelAccessCommand, CanvasAddTagCommand, CanvasContentUpdateCommand, @@ -168,7 +169,7 @@ export class CanvasService { public async giveAccess(command: GiveAccessCommand) { const user = await this.userRepository.findOne({ - where: { id: command.userId }, + where: { id: command.personId }, }); const canvas = await this.canvasRepository.findOne({ where: { id: command.canvasId }, @@ -177,7 +178,10 @@ export class CanvasService { throw new NotFoundException(); } let canvasAccess = await this.canvasAccessRepository.findOne({ - where: { user: { id: command.userId }, canvas: { id: command.canvasId } }, + where: { + user: { id: command.personId }, + canvas: { id: command.canvasId }, + }, }); if (canvasAccess) { return; @@ -190,10 +194,20 @@ export class CanvasService { } public async cancelAccess(command: CancelAccessCommand) { - await this.canvasAccessRepository.delete({ - user: { id: command.userId }, - canvas: { id: command.canvasId }, - }); + let criteria: any; + if (command.userId == command.personId) { + criteria = { + user: { id: command.personId }, + canvas: { id: command.canvasId }, + }; + } else { + criteria = { + user: { id: command.personId }, + canvas: { id: command.canvasId }, + isOwner: false, + }; + } + await this.canvasAccessRepository.delete(criteria); } public async giveAccessByTag(command: GiveAccessByTagCommand) { @@ -208,12 +222,39 @@ export class CanvasService { command.personIds.forEach((personId) => this.giveAccess({ canvasId: canvas.id, - userId: personId, + personId: personId, }), ), ); } + public async cancelAccessByTag(command: CancelAccessByTagCommand) { + const user = await this.userRepository.findOne({ + where: { id: command.userId }, + }); + if (!user) { + throw new NotFoundException(); + } + const accessibleWithTags = await this.readByTags(command.tagIds, user.id); + for (const canvas of accessibleWithTags) { + const accessList = await this.canvasAccessRepository.find({ + where: { + canvas: { id: canvas.id }, + }, + relations: { user: true }, + }); + accessList.forEach((access) => { + if (access.user.id != user.id) { + this.cancelAccess({ + userId: user.id, + canvasId: canvas.id, + personId: access.user.id, + }); + } + }); + } + } + public async addTags(command: CanvasAddTagCommand) { const canvas = await this.canvasRepository.findOne({ where: { id: command.canvasId },