import { Controller, Post, Body, HttpCode, HttpStatus, UseGuards, NotFoundException, ForbiddenException, } from '@nestjs/common'; import { CommentService } from './comment.service'; import { CreateCommentDto } from './dto/create-comment.dto'; import { UpdateCommentDto } from './dto/update-comment.dto'; import { PageIdDto, CommentIdDto } from './dto/comments.input'; import { AuthUser } from '../../common/decorators/auth-user.decorator'; import { AuthWorkspace } from '../../common/decorators/auth-workspace.decorator'; import { JwtAuthGuard } from '../../common/guards/jwt-auth.guard'; import { PaginationOptions } from '@docmost/db/pagination/pagination-options'; import { User, Workspace } from '@docmost/db/types/entity.types'; import SpaceAbilityFactory from '../casl/abilities/space-ability.factory'; import { PageRepo } from '@docmost/db/repos/page/page.repo'; import { SpaceCaslAction, SpaceCaslSubject, } from '../casl/interfaces/space-ability.type'; import { CommentRepo } from '@docmost/db/repos/comment/comment.repo'; @UseGuards(JwtAuthGuard) @Controller('comments') export class CommentController { constructor( private readonly commentService: CommentService, private readonly commentRepo: CommentRepo, private readonly pageRepo: PageRepo, private readonly spaceAbility: SpaceAbilityFactory, ) {} @HttpCode(HttpStatus.OK) @Post('create') async create( @Body() createCommentDto: CreateCommentDto, @AuthUser() user: User, @AuthWorkspace() workspace: Workspace, ) { const page = await this.pageRepo.findById(createCommentDto.pageId); if (!page) { throw new NotFoundException('Page not found'); } const ability = await this.spaceAbility.createForUser(user, page.spaceId); if (ability.cannot(SpaceCaslAction.Create, SpaceCaslSubject.Page)) { throw new ForbiddenException(); } return this.commentService.create( user.id, page.id, workspace.id, createCommentDto, ); } @HttpCode(HttpStatus.OK) @Post('/') async findPageComments( @Body() input: PageIdDto, @Body() pagination: PaginationOptions, @AuthUser() user: User, // @AuthWorkspace() workspace: Workspace, ) { const page = await this.pageRepo.findById(input.pageId); if (!page) { throw new NotFoundException('Page not found'); } const ability = await this.spaceAbility.createForUser(user, page.spaceId); if (ability.cannot(SpaceCaslAction.Read, SpaceCaslSubject.Page)) { throw new ForbiddenException(); } return this.commentService.findByPageId(page.id, pagination); } @HttpCode(HttpStatus.OK) @Post('info') async findOne(@Body() input: CommentIdDto, @AuthUser() user: User) { const comment = await this.commentRepo.findById(input.commentId); if (!comment) { throw new NotFoundException('Comment not found'); } const page = await this.pageRepo.findById(comment.pageId); if (!page) { throw new NotFoundException('Page not found'); } const ability = await this.spaceAbility.createForUser(user, page.spaceId); if (ability.cannot(SpaceCaslAction.Read, SpaceCaslSubject.Page)) { throw new ForbiddenException(); } return comment; } @HttpCode(HttpStatus.OK) @Post('update') update(@Body() updateCommentDto: UpdateCommentDto, @AuthUser() user: User) { //TODO: only comment creators can update their comments return this.commentService.update( updateCommentDto.commentId, updateCommentDto, user, ); } @HttpCode(HttpStatus.OK) @Post('delete') remove(@Body() input: CommentIdDto, @AuthUser() user: User) { // TODO: only comment creators and admins can delete their comments return this.commentService.remove(input.commentId, user); } }