refactor: use new openapi decorator

Also remove fullapi decorator, because it's fully replaced by the openapi decorator.

Signed-off-by: Philip Molares <philip.molares@udo.edu>
This commit is contained in:
Philip Molares 2022-02-07 01:00:32 +01:00 committed by David Mehren
parent a283002a34
commit 89aac9d4b6
14 changed files with 248 additions and 445 deletions

View file

@ -8,20 +8,13 @@ import {
Body, Body,
Controller, Controller,
Delete, Delete,
HttpCode,
Param, Param,
Post, Post,
Put, Put,
UnauthorizedException, UnauthorizedException,
UseGuards, UseGuards,
} from '@nestjs/common'; } from '@nestjs/common';
import { import { ApiTags } from '@nestjs/swagger';
ApiBadRequestResponse,
ApiConflictResponse,
ApiNotFoundResponse,
ApiTags,
ApiUnauthorizedResponse,
} from '@nestjs/swagger';
import { SessionGuard } from '../../../identity/session.guard'; import { SessionGuard } from '../../../identity/session.guard';
import { ConsoleLoggerService } from '../../../logger/console-logger.service'; import { ConsoleLoggerService } from '../../../logger/console-logger.service';
@ -33,15 +26,11 @@ import { NotesService } from '../../../notes/notes.service';
import { PermissionsService } from '../../../permissions/permissions.service'; import { PermissionsService } from '../../../permissions/permissions.service';
import { User } from '../../../users/user.entity'; import { User } from '../../../users/user.entity';
import { UsersService } from '../../../users/users.service'; import { UsersService } from '../../../users/users.service';
import { import { OpenApi } from '../../utils/openapi.decorator';
badRequestDescription,
conflictDescription,
notFoundDescription,
unauthorizedDescription,
} from '../../utils/descriptions';
import { RequestUser } from '../../utils/request-user.decorator'; import { RequestUser } from '../../utils/request-user.decorator';
@UseGuards(SessionGuard) @UseGuards(SessionGuard)
@OpenApi(401)
@ApiTags('alias') @ApiTags('alias')
@Controller('alias') @Controller('alias')
export class AliasController { export class AliasController {
@ -56,10 +45,7 @@ export class AliasController {
} }
@Post() @Post()
@ApiBadRequestResponse({ description: badRequestDescription }) @OpenApi(201, 400, 404, 409)
@ApiConflictResponse({ description: conflictDescription })
@ApiUnauthorizedResponse({ description: unauthorizedDescription })
@ApiNotFoundResponse({ description: notFoundDescription })
async addAlias( async addAlias(
@RequestUser() user: User, @RequestUser() user: User,
@Body() newAliasDto: AliasCreateDto, @Body() newAliasDto: AliasCreateDto,
@ -78,9 +64,7 @@ export class AliasController {
} }
@Put(':alias') @Put(':alias')
@ApiBadRequestResponse({ description: badRequestDescription }) @OpenApi(200, 400, 404)
@ApiUnauthorizedResponse({ description: unauthorizedDescription })
@ApiNotFoundResponse({ description: notFoundDescription })
async makeAliasPrimary( async makeAliasPrimary(
@RequestUser() user: User, @RequestUser() user: User,
@Param('alias') alias: string, @Param('alias') alias: string,
@ -100,12 +84,7 @@ export class AliasController {
} }
@Delete(':alias') @Delete(':alias')
@HttpCode(204) @OpenApi(204, 400, 404)
@ApiUnauthorizedResponse({ description: unauthorizedDescription })
@ApiNotFoundResponse({ description: notFoundDescription })
@ApiBadRequestResponse({
description: badRequestDescription,
})
async removeAlias( async removeAlias(
@RequestUser() user: User, @RequestUser() user: User,
@Param('alias') alias: string, @Param('alias') alias: string,

View file

@ -13,12 +13,7 @@ import {
Req, Req,
UseGuards, UseGuards,
} from '@nestjs/common'; } from '@nestjs/common';
import { import { ApiTags } from '@nestjs/swagger';
ApiBadRequestResponse,
ApiConflictResponse,
ApiTags,
ApiUnauthorizedResponse,
} from '@nestjs/swagger';
import { Session } from 'express-session'; import { Session } from 'express-session';
import { IdentityService } from '../../../identity/identity.service'; import { IdentityService } from '../../../identity/identity.service';
@ -30,12 +25,8 @@ import { SessionGuard } from '../../../identity/session.guard';
import { ConsoleLoggerService } from '../../../logger/console-logger.service'; import { ConsoleLoggerService } from '../../../logger/console-logger.service';
import { User } from '../../../users/user.entity'; import { User } from '../../../users/user.entity';
import { UsersService } from '../../../users/users.service'; import { UsersService } from '../../../users/users.service';
import {
badRequestDescription,
conflictDescription,
unauthorizedDescription,
} from '../../utils/descriptions';
import { LoginEnabledGuard } from '../../utils/login-enabled.guard'; import { LoginEnabledGuard } from '../../utils/login-enabled.guard';
import { OpenApi } from '../../utils/openapi.decorator';
import { RegistrationEnabledGuard } from '../../utils/registration-enabled.guard'; import { RegistrationEnabledGuard } from '../../utils/registration-enabled.guard';
import { RequestUser } from '../../utils/request-user.decorator'; import { RequestUser } from '../../utils/request-user.decorator';
@ -52,8 +43,7 @@ export class AuthController {
@UseGuards(RegistrationEnabledGuard) @UseGuards(RegistrationEnabledGuard)
@Post('local') @Post('local')
@ApiBadRequestResponse({ description: badRequestDescription }) @OpenApi(201, 400, 409)
@ApiConflictResponse({ description: conflictDescription })
async registerUser(@Body() registerDto: RegisterDto): Promise<void> { async registerUser(@Body() registerDto: RegisterDto): Promise<void> {
const user = await this.usersService.createUser( const user = await this.usersService.createUser(
registerDto.username, registerDto.username,
@ -65,8 +55,7 @@ export class AuthController {
@UseGuards(LoginEnabledGuard, SessionGuard) @UseGuards(LoginEnabledGuard, SessionGuard)
@Put('local') @Put('local')
@ApiBadRequestResponse({ description: badRequestDescription }) @OpenApi(200, 400, 401)
@ApiUnauthorizedResponse({ description: unauthorizedDescription })
async updatePassword( async updatePassword(
@RequestUser() user: User, @RequestUser() user: User,
@Body() changePasswordDto: UpdatePasswordDto, @Body() changePasswordDto: UpdatePasswordDto,
@ -84,7 +73,7 @@ export class AuthController {
@UseGuards(LoginEnabledGuard, LocalAuthGuard) @UseGuards(LoginEnabledGuard, LocalAuthGuard)
@Post('local/login') @Post('local/login')
@ApiUnauthorizedResponse({ description: unauthorizedDescription }) @OpenApi(201, 400, 401)
login( login(
@Req() request: Request & { session: { user: string } }, @Req() request: Request & { session: { user: string } },
@Body() loginDto: LoginDto, @Body() loginDto: LoginDto,
@ -95,7 +84,7 @@ export class AuthController {
@UseGuards(SessionGuard) @UseGuards(SessionGuard)
@Delete('logout') @Delete('logout')
@ApiBadRequestResponse({ description: badRequestDescription }) @OpenApi(204, 400, 401)
logout(@Req() request: Request & { session: Session }): void { logout(@Req() request: Request & { session: Session }): void {
request.session.destroy((err) => { request.session.destroy((err) => {
if (err) { if (err) {

View file

@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file) * SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file)
* *
* SPDX-License-Identifier: AGPL-3.0-only * SPDX-License-Identifier: AGPL-3.0-only
*/ */
@ -9,6 +9,7 @@ import { ApiTags } from '@nestjs/swagger';
import { FrontendConfigDto } from '../../../frontend-config/frontend-config.dto'; import { FrontendConfigDto } from '../../../frontend-config/frontend-config.dto';
import { FrontendConfigService } from '../../../frontend-config/frontend-config.service'; import { FrontendConfigService } from '../../../frontend-config/frontend-config.service';
import { ConsoleLoggerService } from '../../../logger/console-logger.service'; import { ConsoleLoggerService } from '../../../logger/console-logger.service';
import { OpenApi } from '../../utils/openapi.decorator';
@ApiTags('config') @ApiTags('config')
@Controller('config') @Controller('config')
@ -21,6 +22,7 @@ export class ConfigController {
} }
@Get() @Get()
@OpenApi(200)
async getFrontendConfig(): Promise<FrontendConfigDto> { async getFrontendConfig(): Promise<FrontendConfigDto> {
return await this.frontendConfigService.getFrontendConfig(); return await this.frontendConfigService.getFrontendConfig();
} }

View file

@ -13,11 +13,7 @@ import {
UseGuards, UseGuards,
UseInterceptors, UseInterceptors,
} from '@nestjs/common'; } from '@nestjs/common';
import { import { ApiTags } from '@nestjs/swagger';
ApiNotFoundResponse,
ApiTags,
ApiUnauthorizedResponse,
} from '@nestjs/swagger';
import { HistoryEntryImportDto } from '../../../../history/history-entry-import.dto'; import { HistoryEntryImportDto } from '../../../../history/history-entry-import.dto';
import { HistoryEntryUpdateDto } from '../../../../history/history-entry-update.dto'; import { HistoryEntryUpdateDto } from '../../../../history/history-entry-update.dto';
@ -27,15 +23,13 @@ import { SessionGuard } from '../../../../identity/session.guard';
import { ConsoleLoggerService } from '../../../../logger/console-logger.service'; import { ConsoleLoggerService } from '../../../../logger/console-logger.service';
import { Note } from '../../../../notes/note.entity'; import { Note } from '../../../../notes/note.entity';
import { User } from '../../../../users/user.entity'; import { User } from '../../../../users/user.entity';
import {
notFoundDescription,
unauthorizedDescription,
} from '../../../utils/descriptions';
import { GetNoteInterceptor } from '../../../utils/get-note.interceptor'; import { GetNoteInterceptor } from '../../../utils/get-note.interceptor';
import { OpenApi } from '../../../utils/openapi.decorator';
import { RequestNote } from '../../../utils/request-note.decorator'; import { RequestNote } from '../../../utils/request-note.decorator';
import { RequestUser } from '../../../utils/request-user.decorator'; import { RequestUser } from '../../../utils/request-user.decorator';
@UseGuards(SessionGuard) @UseGuards(SessionGuard)
@OpenApi(401)
@ApiTags('history') @ApiTags('history')
@Controller('/me/history') @Controller('/me/history')
export class HistoryController { export class HistoryController {
@ -47,8 +41,7 @@ export class HistoryController {
} }
@Get() @Get()
@ApiUnauthorizedResponse({ description: unauthorizedDescription }) @OpenApi(200, 404)
@ApiNotFoundResponse({ description: notFoundDescription })
async getHistory(@RequestUser() user: User): Promise<HistoryEntryDto[]> { async getHistory(@RequestUser() user: User): Promise<HistoryEntryDto[]> {
const foundEntries = await this.historyService.getEntriesByUser(user); const foundEntries = await this.historyService.getEntriesByUser(user);
return await Promise.all( return await Promise.all(
@ -57,8 +50,7 @@ export class HistoryController {
} }
@Post() @Post()
@ApiUnauthorizedResponse({ description: unauthorizedDescription }) @OpenApi(201, 404)
@ApiNotFoundResponse({ description: notFoundDescription })
async setHistory( async setHistory(
@RequestUser() user: User, @RequestUser() user: User,
@Body('history') history: HistoryEntryImportDto[], @Body('history') history: HistoryEntryImportDto[],
@ -67,15 +59,13 @@ export class HistoryController {
} }
@Delete() @Delete()
@ApiUnauthorizedResponse({ description: unauthorizedDescription }) @OpenApi(204, 404)
@ApiNotFoundResponse({ description: notFoundDescription })
async deleteHistory(@RequestUser() user: User): Promise<void> { async deleteHistory(@RequestUser() user: User): Promise<void> {
await this.historyService.deleteHistory(user); await this.historyService.deleteHistory(user);
} }
@Put(':noteIdOrAlias') @Put(':noteIdOrAlias')
@ApiUnauthorizedResponse({ description: unauthorizedDescription }) @OpenApi(200, 404)
@ApiNotFoundResponse({ description: notFoundDescription })
@UseInterceptors(GetNoteInterceptor) @UseInterceptors(GetNoteInterceptor)
async updateHistoryEntry( async updateHistoryEntry(
@RequestNote() note: Note, @RequestNote() note: Note,
@ -91,8 +81,7 @@ export class HistoryController {
} }
@Delete(':noteIdOrAlias') @Delete(':noteIdOrAlias')
@ApiUnauthorizedResponse({ description: unauthorizedDescription }) @OpenApi(204, 404)
@ApiNotFoundResponse({ description: notFoundDescription })
@UseInterceptors(GetNoteInterceptor) @UseInterceptors(GetNoteInterceptor)
async deleteHistoryEntry( async deleteHistoryEntry(
@RequestNote() note: Note, @RequestNote() note: Note,

View file

@ -1,23 +1,10 @@
/* /*
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file) * SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file)
* *
* SPDX-License-Identifier: AGPL-3.0-only * SPDX-License-Identifier: AGPL-3.0-only
*/ */
import { import { Body, Controller, Delete, Get, Post, UseGuards } from '@nestjs/common';
Body, import { ApiTags } from '@nestjs/swagger';
Controller,
Delete,
Get,
HttpCode,
Post,
UseGuards,
} from '@nestjs/common';
import {
ApiInternalServerErrorResponse,
ApiNotFoundResponse,
ApiTags,
ApiUnauthorizedResponse,
} from '@nestjs/swagger';
import { SessionGuard } from '../../../identity/session.guard'; import { SessionGuard } from '../../../identity/session.guard';
import { ConsoleLoggerService } from '../../../logger/console-logger.service'; import { ConsoleLoggerService } from '../../../logger/console-logger.service';
@ -26,14 +13,11 @@ import { MediaService } from '../../../media/media.service';
import { UserInfoDto } from '../../../users/user-info.dto'; import { UserInfoDto } from '../../../users/user-info.dto';
import { User } from '../../../users/user.entity'; import { User } from '../../../users/user.entity';
import { UsersService } from '../../../users/users.service'; import { UsersService } from '../../../users/users.service';
import { import { OpenApi } from '../../utils/openapi.decorator';
internalServerErrorDescription,
notFoundDescription,
unauthorizedDescription,
} from '../../utils/descriptions';
import { RequestUser } from '../../utils/request-user.decorator'; import { RequestUser } from '../../utils/request-user.decorator';
@UseGuards(SessionGuard) @UseGuards(SessionGuard)
@OpenApi(401)
@ApiTags('me') @ApiTags('me')
@Controller('me') @Controller('me')
export class MeController { export class MeController {
@ -45,13 +29,13 @@ export class MeController {
this.logger.setContext(MeController.name); this.logger.setContext(MeController.name);
} }
@Get() @Get()
@ApiUnauthorizedResponse({ description: unauthorizedDescription }) @OpenApi(200)
getMe(@RequestUser() user: User): UserInfoDto { getMe(@RequestUser() user: User): UserInfoDto {
return this.userService.toUserDto(user); return this.userService.toUserDto(user);
} }
@Get('media') @Get('media')
@ApiUnauthorizedResponse({ description: unauthorizedDescription }) @OpenApi(200)
async getMyMedia(@RequestUser() user: User): Promise<MediaUploadDto[]> { async getMyMedia(@RequestUser() user: User): Promise<MediaUploadDto[]> {
const media = await this.mediaService.listUploadsByUser(user); const media = await this.mediaService.listUploadsByUser(user);
return await Promise.all( return await Promise.all(
@ -60,12 +44,7 @@ export class MeController {
} }
@Delete() @Delete()
@HttpCode(204) @OpenApi(204, 404, 500)
@ApiUnauthorizedResponse({ description: unauthorizedDescription })
@ApiNotFoundResponse({ description: notFoundDescription })
@ApiInternalServerErrorResponse({
description: internalServerErrorDescription,
})
async deleteUser(@RequestUser() user: User): Promise<void> { async deleteUser(@RequestUser() user: User): Promise<void> {
const mediaUploads = await this.mediaService.listUploadsByUser(user); const mediaUploads = await this.mediaService.listUploadsByUser(user);
for (const mediaUpload of mediaUploads) { for (const mediaUpload of mediaUploads) {
@ -77,8 +56,7 @@ export class MeController {
} }
@Post('profile') @Post('profile')
@HttpCode(200) @OpenApi(200)
@ApiUnauthorizedResponse({ description: unauthorizedDescription })
async updateDisplayName( async updateDisplayName(
@RequestUser() user: User, @RequestUser() user: User,
@Body('name') newDisplayName: string, @Body('name') newDisplayName: string,

View file

@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file) * SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file)
* *
* SPDX-License-Identifier: AGPL-3.0-only * SPDX-License-Identifier: AGPL-3.0-only
*/ */
@ -7,7 +7,6 @@ import {
Controller, Controller,
Delete, Delete,
Headers, Headers,
HttpCode,
Param, Param,
Post, Post,
UploadedFile, UploadedFile,
@ -15,19 +14,7 @@ import {
UseInterceptors, UseInterceptors,
} from '@nestjs/common'; } from '@nestjs/common';
import { FileInterceptor } from '@nestjs/platform-express'; import { FileInterceptor } from '@nestjs/platform-express';
import { import { ApiBody, ApiConsumes, ApiHeader, ApiTags } from '@nestjs/swagger';
ApiBadRequestResponse,
ApiBody,
ApiConsumes,
ApiCreatedResponse,
ApiForbiddenResponse,
ApiHeader,
ApiInternalServerErrorResponse,
ApiNoContentResponse,
ApiNotFoundResponse,
ApiTags,
ApiUnauthorizedResponse,
} from '@nestjs/swagger';
import { PermissionError } from '../../../errors/errors'; import { PermissionError } from '../../../errors/errors';
import { SessionGuard } from '../../../identity/session.guard'; import { SessionGuard } from '../../../identity/session.guard';
@ -38,18 +25,11 @@ import { MulterFile } from '../../../media/multer-file.interface';
import { Note } from '../../../notes/note.entity'; import { Note } from '../../../notes/note.entity';
import { NotesService } from '../../../notes/notes.service'; import { NotesService } from '../../../notes/notes.service';
import { User } from '../../../users/user.entity'; import { User } from '../../../users/user.entity';
import { import { OpenApi } from '../../utils/openapi.decorator';
badRequestDescription,
forbiddenDescription,
internalServerErrorDescription,
notFoundDescription,
successfullyDeletedDescription,
unauthorizedDescription,
} from '../../utils/descriptions';
import { FullApi } from '../../utils/fullapi-decorator';
import { RequestUser } from '../../utils/request-user.decorator'; import { RequestUser } from '../../utils/request-user.decorator';
@UseGuards(SessionGuard) @UseGuards(SessionGuard)
@OpenApi(401)
@ApiTags('media') @ApiTags('media')
@Controller('media') @Controller('media')
export class MediaController { export class MediaController {
@ -79,18 +59,17 @@ export class MediaController {
description: 'ID or alias of the parent note', description: 'ID or alias of the parent note',
}) })
@UseInterceptors(FileInterceptor('file')) @UseInterceptors(FileInterceptor('file'))
@HttpCode(201) @OpenApi(
@ApiCreatedResponse({ {
description: 'The file was uploaded successfully', code: 201,
type: MediaUploadUrlDto, description: 'The file was uploaded successfully',
}) dto: MediaUploadUrlDto,
@ApiBadRequestResponse({ description: badRequestDescription }) },
@ApiUnauthorizedResponse({ description: unauthorizedDescription }) 400,
@ApiForbiddenResponse({ description: forbiddenDescription }) 403,
@ApiNotFoundResponse({ description: notFoundDescription }) 404,
@ApiInternalServerErrorResponse({ 500,
description: internalServerErrorDescription, )
})
async uploadMedia( async uploadMedia(
@UploadedFile() file: MulterFile, @UploadedFile() file: MulterFile,
@Headers('HedgeDoc-Note') noteId: string, @Headers('HedgeDoc-Note') noteId: string,
@ -107,12 +86,7 @@ export class MediaController {
} }
@Delete(':filename') @Delete(':filename')
@HttpCode(204) @OpenApi(204, 403, 404, 500)
@ApiNoContentResponse({ description: successfullyDeletedDescription })
@FullApi
@ApiInternalServerErrorResponse({
description: internalServerErrorDescription,
})
async deleteMedia( async deleteMedia(
@RequestUser() user: User, @RequestUser() user: User,
@Param('filename') filename: string, @Param('filename') filename: string,

View file

@ -8,20 +8,12 @@ import {
Controller, Controller,
Delete, Delete,
Get, Get,
HttpCode,
Param, Param,
Post, Post,
UseGuards, UseGuards,
UseInterceptors, UseInterceptors,
} from '@nestjs/common'; } from '@nestjs/common';
import { import { ApiTags } from '@nestjs/swagger';
ApiBadRequestResponse,
ApiConflictResponse,
ApiInternalServerErrorResponse,
ApiNotFoundResponse,
ApiTags,
ApiUnauthorizedResponse,
} from '@nestjs/swagger';
import { HistoryService } from '../../../history/history.service'; import { HistoryService } from '../../../history/history.service';
import { SessionGuard } from '../../../identity/session.guard'; import { SessionGuard } from '../../../identity/session.guard';
@ -38,21 +30,16 @@ import { RevisionDto } from '../../../revisions/revision.dto';
import { RevisionsService } from '../../../revisions/revisions.service'; import { RevisionsService } from '../../../revisions/revisions.service';
import { User } from '../../../users/user.entity'; import { User } from '../../../users/user.entity';
import { UsersService } from '../../../users/users.service'; import { UsersService } from '../../../users/users.service';
import {
badRequestDescription,
conflictDescription,
internalServerErrorDescription,
notFoundDescription,
unauthorizedDescription,
} from '../../utils/descriptions';
import { GetNoteInterceptor } from '../../utils/get-note.interceptor'; import { GetNoteInterceptor } from '../../utils/get-note.interceptor';
import { MarkdownBody } from '../../utils/markdown-body.decorator'; import { MarkdownBody } from '../../utils/markdown-body.decorator';
import { OpenApi } from '../../utils/openapi.decorator';
import { Permissions } from '../../utils/permissions.decorator'; import { Permissions } from '../../utils/permissions.decorator';
import { PermissionsGuard } from '../../utils/permissions.guard'; import { PermissionsGuard } from '../../utils/permissions.guard';
import { RequestNote } from '../../utils/request-note.decorator'; import { RequestNote } from '../../utils/request-note.decorator';
import { RequestUser } from '../../utils/request-user.decorator'; import { RequestUser } from '../../utils/request-user.decorator';
@UseGuards(SessionGuard) @UseGuards(SessionGuard, PermissionsGuard)
@OpenApi(401, 403)
@ApiTags('notes') @ApiTags('notes')
@Controller('notes') @Controller('notes')
export class NotesController { export class NotesController {
@ -68,10 +55,9 @@ export class NotesController {
} }
@Get(':noteIdOrAlias') @Get(':noteIdOrAlias')
@ApiUnauthorizedResponse({ description: unauthorizedDescription }) @OpenApi(200)
@Permissions(Permission.READ) @Permissions(Permission.READ)
@UseInterceptors(GetNoteInterceptor) @UseInterceptors(GetNoteInterceptor)
@UseGuards(PermissionsGuard)
async getNote( async getNote(
@RequestUser() user: User, @RequestUser() user: User,
@RequestNote() note: Note, @RequestNote() note: Note,
@ -81,10 +67,9 @@ export class NotesController {
} }
@Get(':noteIdOrAlias/media') @Get(':noteIdOrAlias/media')
@ApiUnauthorizedResponse({ description: unauthorizedDescription }) @OpenApi(200)
@Permissions(Permission.READ) @Permissions(Permission.READ)
@UseInterceptors(GetNoteInterceptor) @UseInterceptors(GetNoteInterceptor)
@UseGuards(PermissionsGuard)
async getNotesMedia(@RequestNote() note: Note): Promise<MediaUploadDto[]> { async getNotesMedia(@RequestNote() note: Note): Promise<MediaUploadDto[]> {
const media = await this.mediaService.listUploadsByNote(note); const media = await this.mediaService.listUploadsByNote(note);
return await Promise.all( return await Promise.all(
@ -93,10 +78,8 @@ export class NotesController {
} }
@Post() @Post()
@HttpCode(201) @OpenApi(201)
@ApiUnauthorizedResponse({ description: unauthorizedDescription })
@Permissions(Permission.CREATE) @Permissions(Permission.CREATE)
@UseGuards(PermissionsGuard)
async createNote( async createNote(
@RequestUser() user: User, @RequestUser() user: User,
@MarkdownBody() text: string, @MarkdownBody() text: string,
@ -108,13 +91,8 @@ export class NotesController {
} }
@Post(':noteAlias') @Post(':noteAlias')
@HttpCode(201) @OpenApi(201, 400, 404, 409)
@ApiBadRequestResponse({ description: badRequestDescription })
@ApiConflictResponse({ description: conflictDescription })
@ApiUnauthorizedResponse({ description: unauthorizedDescription })
@ApiNotFoundResponse({ description: notFoundDescription })
@Permissions(Permission.CREATE) @Permissions(Permission.CREATE)
@UseGuards(PermissionsGuard)
async createNamedNote( async createNamedNote(
@RequestUser() user: User, @RequestUser() user: User,
@Param('noteAlias') noteAlias: string, @Param('noteAlias') noteAlias: string,
@ -127,15 +105,9 @@ export class NotesController {
} }
@Delete(':noteIdOrAlias') @Delete(':noteIdOrAlias')
@HttpCode(204) @OpenApi(204, 404, 500)
@ApiUnauthorizedResponse({ description: unauthorizedDescription })
@ApiNotFoundResponse({ description: notFoundDescription })
@ApiInternalServerErrorResponse({
description: internalServerErrorDescription,
})
@Permissions(Permission.OWNER) @Permissions(Permission.OWNER)
@UseInterceptors(GetNoteInterceptor) @UseInterceptors(GetNoteInterceptor)
@UseGuards(PermissionsGuard)
async deleteNote( async deleteNote(
@RequestUser() user: User, @RequestUser() user: User,
@RequestNote() note: Note, @RequestNote() note: Note,
@ -156,11 +128,9 @@ export class NotesController {
} }
@Get(':noteIdOrAlias/revisions') @Get(':noteIdOrAlias/revisions')
@ApiUnauthorizedResponse({ description: unauthorizedDescription }) @OpenApi(200, 404)
@ApiNotFoundResponse({ description: notFoundDescription })
@Permissions(Permission.READ) @Permissions(Permission.READ)
@UseInterceptors(GetNoteInterceptor) @UseInterceptors(GetNoteInterceptor)
@UseGuards(PermissionsGuard)
async getNoteRevisions( async getNoteRevisions(
@RequestUser() user: User, @RequestUser() user: User,
@RequestNote() note: Note, @RequestNote() note: Note,
@ -174,12 +144,9 @@ export class NotesController {
} }
@Delete(':noteIdOrAlias/revisions') @Delete(':noteIdOrAlias/revisions')
@HttpCode(204) @OpenApi(204, 404)
@ApiUnauthorizedResponse({ description: unauthorizedDescription })
@ApiNotFoundResponse({ description: notFoundDescription })
@Permissions(Permission.READ) @Permissions(Permission.READ)
@UseInterceptors(GetNoteInterceptor) @UseInterceptors(GetNoteInterceptor)
@UseGuards(PermissionsGuard)
async purgeNoteRevisions( async purgeNoteRevisions(
@RequestUser() user: User, @RequestUser() user: User,
@RequestNote() note: Note, @RequestNote() note: Note,
@ -197,11 +164,9 @@ export class NotesController {
} }
@Get(':noteIdOrAlias/revisions/:revisionId') @Get(':noteIdOrAlias/revisions/:revisionId')
@ApiUnauthorizedResponse({ description: unauthorizedDescription }) @OpenApi(200, 404)
@ApiNotFoundResponse({ description: notFoundDescription })
@Permissions(Permission.READ) @Permissions(Permission.READ)
@UseInterceptors(GetNoteInterceptor) @UseInterceptors(GetNoteInterceptor)
@UseGuards(PermissionsGuard)
async getNoteRevision( async getNoteRevision(
@RequestUser() user: User, @RequestUser() user: User,
@RequestNote() note: Note, @RequestNote() note: Note,

View file

@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file) * SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file)
* *
* SPDX-License-Identifier: AGPL-3.0-only * SPDX-License-Identifier: AGPL-3.0-only
*/ */
@ -8,17 +8,12 @@ import {
Controller, Controller,
Delete, Delete,
Get, Get,
HttpCode,
Param, Param,
Post, Post,
UnauthorizedException, UnauthorizedException,
UseGuards, UseGuards,
} from '@nestjs/common'; } from '@nestjs/common';
import { import { ApiTags } from '@nestjs/swagger';
ApiNotFoundResponse,
ApiTags,
ApiUnauthorizedResponse,
} from '@nestjs/swagger';
import { AuthTokenWithSecretDto } from '../../../auth/auth-token-with-secret.dto'; import { AuthTokenWithSecretDto } from '../../../auth/auth-token-with-secret.dto';
import { AuthTokenDto } from '../../../auth/auth-token.dto'; import { AuthTokenDto } from '../../../auth/auth-token.dto';
@ -27,13 +22,11 @@ import { SessionGuard } from '../../../identity/session.guard';
import { ConsoleLoggerService } from '../../../logger/console-logger.service'; import { ConsoleLoggerService } from '../../../logger/console-logger.service';
import { User } from '../../../users/user.entity'; import { User } from '../../../users/user.entity';
import { TimestampMillis } from '../../../utils/timestamp'; import { TimestampMillis } from '../../../utils/timestamp';
import { import { OpenApi } from '../../utils/openapi.decorator';
notFoundDescription,
unauthorizedDescription,
} from '../../utils/descriptions';
import { RequestUser } from '../../utils/request-user.decorator'; import { RequestUser } from '../../utils/request-user.decorator';
@UseGuards(SessionGuard) @UseGuards(SessionGuard)
@OpenApi(401)
@ApiTags('tokens') @ApiTags('tokens')
@Controller('tokens') @Controller('tokens')
export class TokensController { export class TokensController {
@ -45,7 +38,7 @@ export class TokensController {
} }
@Get() @Get()
@ApiUnauthorizedResponse({ description: unauthorizedDescription }) @OpenApi(200)
async getUserTokens(@RequestUser() user: User): Promise<AuthTokenDto[]> { async getUserTokens(@RequestUser() user: User): Promise<AuthTokenDto[]> {
return (await this.authService.getTokensByUser(user)).map((token) => return (await this.authService.getTokensByUser(user)).map((token) =>
this.authService.toAuthTokenDto(token), this.authService.toAuthTokenDto(token),
@ -53,7 +46,7 @@ export class TokensController {
} }
@Post() @Post()
@ApiUnauthorizedResponse({ description: unauthorizedDescription }) @OpenApi(201)
async postTokenRequest( async postTokenRequest(
@Body('label') label: string, @Body('label') label: string,
@Body('validUntil') validUntil: TimestampMillis, @Body('validUntil') validUntil: TimestampMillis,
@ -63,9 +56,7 @@ export class TokensController {
} }
@Delete('/:keyId') @Delete('/:keyId')
@HttpCode(204) @OpenApi(204, 404)
@ApiUnauthorizedResponse({ description: unauthorizedDescription })
@ApiNotFoundResponse({ description: notFoundDescription })
async deleteToken( async deleteToken(
@RequestUser() user: User, @RequestUser() user: User,
@Param('keyId') keyId: string, @Param('keyId') keyId: string,

View file

@ -8,20 +8,13 @@ import {
Body, Body,
Controller, Controller,
Delete, Delete,
HttpCode,
Param, Param,
Post, Post,
Put, Put,
UnauthorizedException, UnauthorizedException,
UseGuards, UseGuards,
} from '@nestjs/common'; } from '@nestjs/common';
import { import { ApiSecurity, ApiTags } from '@nestjs/swagger';
ApiBadRequestResponse,
ApiNoContentResponse,
ApiOkResponse,
ApiSecurity,
ApiTags,
} from '@nestjs/swagger';
import { TokenAuthGuard } from '../../../auth/token.strategy'; import { TokenAuthGuard } from '../../../auth/token.strategy';
import { ConsoleLoggerService } from '../../../logger/console-logger.service'; import { ConsoleLoggerService } from '../../../logger/console-logger.service';
@ -32,11 +25,11 @@ import { AliasService } from '../../../notes/alias.service';
import { NotesService } from '../../../notes/notes.service'; import { NotesService } from '../../../notes/notes.service';
import { PermissionsService } from '../../../permissions/permissions.service'; import { PermissionsService } from '../../../permissions/permissions.service';
import { User } from '../../../users/user.entity'; import { User } from '../../../users/user.entity';
import { badRequestDescription } from '../../utils/descriptions'; import { OpenApi } from '../../utils/openapi.decorator';
import { FullApi } from '../../utils/fullapi-decorator';
import { RequestUser } from '../../utils/request-user.decorator'; import { RequestUser } from '../../utils/request-user.decorator';
@UseGuards(TokenAuthGuard) @UseGuards(TokenAuthGuard)
@OpenApi(401)
@ApiTags('alias') @ApiTags('alias')
@ApiSecurity('token') @ApiSecurity('token')
@Controller('alias') @Controller('alias')
@ -51,11 +44,15 @@ export class AliasController {
} }
@Post() @Post()
@ApiOkResponse({ @OpenApi(
description: 'The new alias', {
type: AliasDto, code: 200,
}) description: 'The new alias',
@FullApi dto: AliasDto,
},
403,
404,
)
async addAlias( async addAlias(
@RequestUser() user: User, @RequestUser() user: User,
@Body() newAliasDto: AliasCreateDto, @Body() newAliasDto: AliasCreateDto,
@ -74,11 +71,15 @@ export class AliasController {
} }
@Put(':alias') @Put(':alias')
@ApiOkResponse({ @OpenApi(
description: 'The updated alias', {
type: AliasDto, code: 200,
}) description: 'The updated alias',
@FullApi dto: AliasDto,
},
403,
404,
)
async makeAliasPrimary( async makeAliasPrimary(
@RequestUser() user: User, @RequestUser() user: User,
@Param('alias') alias: string, @Param('alias') alias: string,
@ -98,14 +99,15 @@ export class AliasController {
} }
@Delete(':alias') @Delete(':alias')
@HttpCode(204) @OpenApi(
@ApiNoContentResponse({ {
description: 'The alias was deleted', code: 204,
}) description: 'The alias was deleted',
@FullApi },
@ApiBadRequestResponse({ 400,
description: badRequestDescription, 403,
}) 404,
)
async removeAlias( async removeAlias(
@RequestUser() user: User, @RequestUser() user: User,
@Param('alias') alias: string, @Param('alias') alias: string,

View file

@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file) * SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file)
* *
* SPDX-License-Identifier: AGPL-3.0-only * SPDX-License-Identifier: AGPL-3.0-only
*/ */
@ -8,19 +8,11 @@ import {
Controller, Controller,
Delete, Delete,
Get, Get,
HttpCode,
Put, Put,
UseGuards, UseGuards,
UseInterceptors, UseInterceptors,
} from '@nestjs/common'; } from '@nestjs/common';
import { import { ApiSecurity, ApiTags } from '@nestjs/swagger';
ApiNoContentResponse,
ApiNotFoundResponse,
ApiOkResponse,
ApiSecurity,
ApiTags,
ApiUnauthorizedResponse,
} from '@nestjs/swagger';
import { TokenAuthGuard } from '../../../auth/token.strategy'; import { TokenAuthGuard } from '../../../auth/token.strategy';
import { HistoryEntryUpdateDto } from '../../../history/history-entry-update.dto'; import { HistoryEntryUpdateDto } from '../../../history/history-entry-update.dto';
@ -35,16 +27,13 @@ import { NotesService } from '../../../notes/notes.service';
import { UserInfoDto } from '../../../users/user-info.dto'; import { UserInfoDto } from '../../../users/user-info.dto';
import { User } from '../../../users/user.entity'; import { User } from '../../../users/user.entity';
import { UsersService } from '../../../users/users.service'; import { UsersService } from '../../../users/users.service';
import {
notFoundDescription,
successfullyDeletedDescription,
unauthorizedDescription,
} from '../../utils/descriptions';
import { GetNoteInterceptor } from '../../utils/get-note.interceptor'; import { GetNoteInterceptor } from '../../utils/get-note.interceptor';
import { OpenApi } from '../../utils/openapi.decorator';
import { RequestNote } from '../../utils/request-note.decorator'; import { RequestNote } from '../../utils/request-note.decorator';
import { RequestUser } from '../../utils/request-user.decorator'; import { RequestUser } from '../../utils/request-user.decorator';
@UseGuards(TokenAuthGuard) @UseGuards(TokenAuthGuard)
@OpenApi(401)
@ApiTags('me') @ApiTags('me')
@ApiSecurity('token') @ApiSecurity('token')
@Controller('me') @Controller('me')
@ -60,22 +49,22 @@ export class MeController {
} }
@Get() @Get()
@ApiOkResponse({ @OpenApi({
code: 200,
description: 'The user information', description: 'The user information',
type: UserInfoDto, dto: UserInfoDto,
}) })
@ApiUnauthorizedResponse({ description: unauthorizedDescription })
getMe(@RequestUser() user: User): UserInfoDto { getMe(@RequestUser() user: User): UserInfoDto {
return this.usersService.toUserDto(user); return this.usersService.toUserDto(user);
} }
@Get('history') @Get('history')
@ApiOkResponse({ @OpenApi({
code: 200,
description: 'The history entries of the user', description: 'The history entries of the user',
isArray: true, isArray: true,
type: HistoryEntryDto, dto: HistoryEntryDto,
}) })
@ApiUnauthorizedResponse({ description: unauthorizedDescription })
async getUserHistory(@RequestUser() user: User): Promise<HistoryEntryDto[]> { async getUserHistory(@RequestUser() user: User): Promise<HistoryEntryDto[]> {
const foundEntries = await this.historyService.getEntriesByUser(user); const foundEntries = await this.historyService.getEntriesByUser(user);
return await Promise.all( return await Promise.all(
@ -85,12 +74,14 @@ export class MeController {
@UseInterceptors(GetNoteInterceptor) @UseInterceptors(GetNoteInterceptor)
@Get('history/:noteIdOrAlias') @Get('history/:noteIdOrAlias')
@ApiOkResponse({ @OpenApi(
description: 'The history entry of the user which points to the note', {
type: HistoryEntryDto, code: 200,
}) description: 'The history entry of the user which points to the note',
@ApiUnauthorizedResponse({ description: unauthorizedDescription }) dto: HistoryEntryDto,
@ApiNotFoundResponse({ description: notFoundDescription }) },
404,
)
async getHistoryEntry( async getHistoryEntry(
@RequestUser() user: User, @RequestUser() user: User,
@RequestNote() note: Note, @RequestNote() note: Note,
@ -101,12 +92,14 @@ export class MeController {
@UseInterceptors(GetNoteInterceptor) @UseInterceptors(GetNoteInterceptor)
@Put('history/:noteIdOrAlias') @Put('history/:noteIdOrAlias')
@ApiOkResponse({ @OpenApi(
description: 'The updated history entry', {
type: HistoryEntryDto, code: 200,
}) description: 'The updated history entry',
@ApiUnauthorizedResponse({ description: unauthorizedDescription }) dto: HistoryEntryDto,
@ApiNotFoundResponse({ description: notFoundDescription }) },
404,
)
async updateHistoryEntry( async updateHistoryEntry(
@RequestUser() user: User, @RequestUser() user: User,
@RequestNote() note: Note, @RequestNote() note: Note,
@ -120,10 +113,7 @@ export class MeController {
@UseInterceptors(GetNoteInterceptor) @UseInterceptors(GetNoteInterceptor)
@Delete('history/:noteIdOrAlias') @Delete('history/:noteIdOrAlias')
@HttpCode(204) @OpenApi(204, 404)
@ApiNoContentResponse({ description: successfullyDeletedDescription })
@ApiUnauthorizedResponse({ description: unauthorizedDescription })
@ApiNotFoundResponse({ description: notFoundDescription })
async deleteHistoryEntry( async deleteHistoryEntry(
@RequestUser() user: User, @RequestUser() user: User,
@RequestNote() note: Note, @RequestNote() note: Note,
@ -133,12 +123,12 @@ export class MeController {
} }
@Get('notes') @Get('notes')
@ApiOkResponse({ @OpenApi({
code: 200,
description: 'Metadata of all notes of the user', description: 'Metadata of all notes of the user',
isArray: true, isArray: true,
type: NoteMetadataDto, dto: NoteMetadataDto,
}) })
@ApiUnauthorizedResponse({ description: unauthorizedDescription })
async getMyNotes(@RequestUser() user: User): Promise<NoteMetadataDto[]> { async getMyNotes(@RequestUser() user: User): Promise<NoteMetadataDto[]> {
const notes = this.notesService.getUserNotes(user); const notes = this.notesService.getUserNotes(user);
return await Promise.all( return await Promise.all(
@ -147,12 +137,12 @@ export class MeController {
} }
@Get('media') @Get('media')
@ApiOkResponse({ @OpenApi({
code: 200,
description: 'All media uploads of the user', description: 'All media uploads of the user',
isArray: true, isArray: true,
type: MediaUploadDto, dto: MediaUploadDto,
}) })
@ApiUnauthorizedResponse({ description: unauthorizedDescription })
async getMyMedia(@RequestUser() user: User): Promise<MediaUploadDto[]> { async getMyMedia(@RequestUser() user: User): Promise<MediaUploadDto[]> {
const media = await this.mediaService.listUploadsByUser(user); const media = await this.mediaService.listUploadsByUser(user);
return await Promise.all( return await Promise.all(

View file

@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file) * SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file)
* *
* SPDX-License-Identifier: AGPL-3.0-only * SPDX-License-Identifier: AGPL-3.0-only
*/ */
@ -7,7 +7,6 @@ import {
Controller, Controller,
Delete, Delete,
Headers, Headers,
HttpCode,
Param, Param,
Post, Post,
UploadedFile, UploadedFile,
@ -16,18 +15,11 @@ import {
} from '@nestjs/common'; } from '@nestjs/common';
import { FileInterceptor } from '@nestjs/platform-express'; import { FileInterceptor } from '@nestjs/platform-express';
import { import {
ApiBadRequestResponse,
ApiBody, ApiBody,
ApiConsumes, ApiConsumes,
ApiCreatedResponse,
ApiForbiddenResponse,
ApiHeader, ApiHeader,
ApiInternalServerErrorResponse,
ApiNoContentResponse,
ApiNotFoundResponse,
ApiSecurity, ApiSecurity,
ApiTags, ApiTags,
ApiUnauthorizedResponse,
} from '@nestjs/swagger'; } from '@nestjs/swagger';
import { TokenAuthGuard } from '../../../auth/token.strategy'; import { TokenAuthGuard } from '../../../auth/token.strategy';
@ -39,18 +31,11 @@ import { MulterFile } from '../../../media/multer-file.interface';
import { Note } from '../../../notes/note.entity'; import { Note } from '../../../notes/note.entity';
import { NotesService } from '../../../notes/notes.service'; import { NotesService } from '../../../notes/notes.service';
import { User } from '../../../users/user.entity'; import { User } from '../../../users/user.entity';
import { import { OpenApi } from '../../utils/openapi.decorator';
badRequestDescription,
forbiddenDescription,
internalServerErrorDescription,
notFoundDescription,
successfullyDeletedDescription,
unauthorizedDescription,
} from '../../utils/descriptions';
import { FullApi } from '../../utils/fullapi-decorator';
import { RequestUser } from '../../utils/request-user.decorator'; import { RequestUser } from '../../utils/request-user.decorator';
@UseGuards(TokenAuthGuard) @UseGuards(TokenAuthGuard)
@OpenApi(401)
@ApiTags('media') @ApiTags('media')
@ApiSecurity('token') @ApiSecurity('token')
@Controller('media') @Controller('media')
@ -80,19 +65,18 @@ export class MediaController {
name: 'HedgeDoc-Note', name: 'HedgeDoc-Note',
description: 'ID or alias of the parent note', description: 'ID or alias of the parent note',
}) })
@ApiCreatedResponse({ @OpenApi(
description: 'The file was uploaded successfully', {
type: MediaUploadUrlDto, code: 201,
}) description: 'The file was uploaded successfully',
@ApiBadRequestResponse({ description: badRequestDescription }) dto: MediaUploadUrlDto,
@ApiUnauthorizedResponse({ description: unauthorizedDescription }) },
@ApiForbiddenResponse({ description: forbiddenDescription }) 400,
@ApiNotFoundResponse({ description: notFoundDescription }) 403,
@ApiInternalServerErrorResponse({ 404,
description: internalServerErrorDescription, 500,
}) )
@UseInterceptors(FileInterceptor('file')) @UseInterceptors(FileInterceptor('file'))
@HttpCode(201)
async uploadMedia( async uploadMedia(
@RequestUser() user: User, @RequestUser() user: User,
@UploadedFile() file: MulterFile, @UploadedFile() file: MulterFile,
@ -109,12 +93,7 @@ export class MediaController {
} }
@Delete(':filename') @Delete(':filename')
@HttpCode(204) @OpenApi(204, 403, 404, 500)
@ApiNoContentResponse({ description: successfullyDeletedDescription })
@ApiInternalServerErrorResponse({
description: internalServerErrorDescription,
})
@FullApi
async deleteMedia( async deleteMedia(
@RequestUser() user: User, @RequestUser() user: User,
@Param('filename') filename: string, @Param('filename') filename: string,

View file

@ -1,27 +1,18 @@
/* /*
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file) * SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file)
* *
* SPDX-License-Identifier: AGPL-3.0-only * SPDX-License-Identifier: AGPL-3.0-only
*/ */
import { Controller, Get, UseGuards } from '@nestjs/common'; import { Controller, Get, UseGuards } from '@nestjs/common';
import { import { ApiSecurity, ApiTags } from '@nestjs/swagger';
ApiForbiddenResponse,
ApiOkResponse,
ApiProduces,
ApiSecurity,
ApiTags,
ApiUnauthorizedResponse,
} from '@nestjs/swagger';
import { TokenAuthGuard } from '../../../auth/token.strategy'; import { TokenAuthGuard } from '../../../auth/token.strategy';
import { MonitoringService } from '../../../monitoring/monitoring.service'; import { MonitoringService } from '../../../monitoring/monitoring.service';
import { ServerStatusDto } from '../../../monitoring/server-status.dto'; import { ServerStatusDto } from '../../../monitoring/server-status.dto';
import { import { OpenApi } from '../../utils/openapi.decorator';
forbiddenDescription,
unauthorizedDescription,
} from '../../utils/descriptions';
@UseGuards(TokenAuthGuard) @UseGuards(TokenAuthGuard)
@OpenApi(401)
@ApiTags('monitoring') @ApiTags('monitoring')
@ApiSecurity('token') @ApiSecurity('token')
@Controller('monitoring') @Controller('monitoring')
@ -29,24 +20,28 @@ export class MonitoringController {
constructor(private monitoringService: MonitoringService) {} constructor(private monitoringService: MonitoringService) {}
@Get() @Get()
@ApiOkResponse({ @OpenApi(
description: 'The server info', {
type: ServerStatusDto, code: 200,
}) description: 'The server info',
@ApiUnauthorizedResponse({ description: unauthorizedDescription }) dto: ServerStatusDto,
@ApiForbiddenResponse({ description: forbiddenDescription }) },
403,
)
getStatus(): Promise<ServerStatusDto> { getStatus(): Promise<ServerStatusDto> {
// TODO: toServerStatusDto. // TODO: toServerStatusDto.
return this.monitoringService.getServerStatus(); return this.monitoringService.getServerStatus();
} }
@Get('prometheus') @Get('prometheus')
@ApiOkResponse({ @OpenApi(
description: 'Prometheus compatible monitoring data', {
}) code: 200,
@ApiUnauthorizedResponse({ description: unauthorizedDescription }) description: 'Prometheus compatible monitoring data',
@ApiForbiddenResponse({ description: forbiddenDescription }) mimeType: 'text/plain',
@ApiProduces('text/plain') },
403,
)
getPrometheusStatus(): string { getPrometheusStatus(): string {
return ''; return '';
} }

View file

@ -8,27 +8,13 @@ import {
Controller, Controller,
Delete, Delete,
Get, Get,
Header,
HttpCode,
Param, Param,
Post, Post,
Put, Put,
UseGuards, UseGuards,
UseInterceptors, UseInterceptors,
} from '@nestjs/common'; } from '@nestjs/common';
import { import { ApiSecurity, ApiTags } from '@nestjs/swagger';
ApiBadRequestResponse,
ApiConflictResponse,
ApiCreatedResponse,
ApiForbiddenResponse,
ApiInternalServerErrorResponse,
ApiNoContentResponse,
ApiOkResponse,
ApiProduces,
ApiSecurity,
ApiTags,
ApiUnauthorizedResponse,
} from '@nestjs/swagger';
import { TokenAuthGuard } from '../../../auth/token.strategy'; import { TokenAuthGuard } from '../../../auth/token.strategy';
import { HistoryService } from '../../../history/history.service'; import { HistoryService } from '../../../history/history.service';
@ -49,23 +35,16 @@ import { RevisionMetadataDto } from '../../../revisions/revision-metadata.dto';
import { RevisionDto } from '../../../revisions/revision.dto'; import { RevisionDto } from '../../../revisions/revision.dto';
import { RevisionsService } from '../../../revisions/revisions.service'; import { RevisionsService } from '../../../revisions/revisions.service';
import { User } from '../../../users/user.entity'; import { User } from '../../../users/user.entity';
import {
badRequestDescription,
conflictDescription,
forbiddenDescription,
internalServerErrorDescription,
successfullyDeletedDescription,
unauthorizedDescription,
} from '../../utils/descriptions';
import { FullApi } from '../../utils/fullapi-decorator';
import { GetNoteInterceptor } from '../../utils/get-note.interceptor'; import { GetNoteInterceptor } from '../../utils/get-note.interceptor';
import { MarkdownBody } from '../../utils/markdown-body.decorator'; import { MarkdownBody } from '../../utils/markdown-body.decorator';
import { OpenApi } from '../../utils/openapi.decorator';
import { Permissions } from '../../utils/permissions.decorator'; import { Permissions } from '../../utils/permissions.decorator';
import { PermissionsGuard } from '../../utils/permissions.guard'; import { PermissionsGuard } from '../../utils/permissions.guard';
import { RequestNote } from '../../utils/request-note.decorator'; import { RequestNote } from '../../utils/request-note.decorator';
import { RequestUser } from '../../utils/request-user.decorator'; import { RequestUser } from '../../utils/request-user.decorator';
@UseGuards(TokenAuthGuard) @UseGuards(TokenAuthGuard, PermissionsGuard)
@OpenApi(401)
@ApiTags('notes') @ApiTags('notes')
@ApiSecurity('token') @ApiSecurity('token')
@Controller('notes') @Controller('notes')
@ -81,11 +60,8 @@ export class NotesController {
} }
@Permissions(Permission.CREATE) @Permissions(Permission.CREATE)
@UseGuards(TokenAuthGuard, PermissionsGuard)
@Post() @Post()
@HttpCode(201) @OpenApi(201, 403, 409)
@ApiUnauthorizedResponse({ description: unauthorizedDescription })
@ApiForbiddenResponse({ description: forbiddenDescription })
async createNote( async createNote(
@RequestUser() user: User, @RequestUser() user: User,
@MarkdownBody() text: string, @MarkdownBody() text: string,
@ -98,13 +74,16 @@ export class NotesController {
@UseInterceptors(GetNoteInterceptor) @UseInterceptors(GetNoteInterceptor)
@Permissions(Permission.READ) @Permissions(Permission.READ)
@UseGuards(PermissionsGuard)
@Get(':noteIdOrAlias') @Get(':noteIdOrAlias')
@ApiOkResponse({ @OpenApi(
description: 'Get information about the newly created note', {
type: NoteDto, code: 200,
}) description: 'Get information about the newly created note',
@FullApi dto: NoteDto,
},
403,
404,
)
async getNote( async getNote(
@RequestUser() user: User, @RequestUser() user: User,
@RequestNote() note: Note, @RequestNote() note: Note,
@ -116,15 +95,16 @@ export class NotesController {
@Permissions(Permission.CREATE) @Permissions(Permission.CREATE)
@UseGuards(PermissionsGuard) @UseGuards(PermissionsGuard)
@Post(':noteAlias') @Post(':noteAlias')
@HttpCode(201) @OpenApi(
@ApiCreatedResponse({ {
description: 'Get information about the newly created note', code: 201,
type: NoteDto, description: 'Get information about the newly created note',
}) dto: NoteDto,
@ApiBadRequestResponse({ description: badRequestDescription }) },
@ApiConflictResponse({ description: conflictDescription }) 400,
@ApiUnauthorizedResponse({ description: unauthorizedDescription }) 403,
@ApiForbiddenResponse({ description: forbiddenDescription }) 409,
)
async createNamedNote( async createNamedNote(
@RequestUser() user: User, @RequestUser() user: User,
@Param('noteAlias') noteAlias: string, @Param('noteAlias') noteAlias: string,
@ -138,14 +118,8 @@ export class NotesController {
@UseInterceptors(GetNoteInterceptor) @UseInterceptors(GetNoteInterceptor)
@Permissions(Permission.OWNER) @Permissions(Permission.OWNER)
@UseGuards(PermissionsGuard)
@Delete(':noteIdOrAlias') @Delete(':noteIdOrAlias')
@HttpCode(204) @OpenApi(204, 403, 404, 500)
@ApiNoContentResponse({ description: successfullyDeletedDescription })
@FullApi
@ApiInternalServerErrorResponse({
description: internalServerErrorDescription,
})
async deleteNote( async deleteNote(
@RequestUser() user: User, @RequestUser() user: User,
@RequestNote() note: Note, @RequestNote() note: Note,
@ -167,13 +141,16 @@ export class NotesController {
@UseInterceptors(GetNoteInterceptor) @UseInterceptors(GetNoteInterceptor)
@Permissions(Permission.WRITE) @Permissions(Permission.WRITE)
@UseGuards(PermissionsGuard)
@Put(':noteIdOrAlias') @Put(':noteIdOrAlias')
@ApiOkResponse({ @OpenApi(
description: 'The new, changed note', {
type: NoteDto, code: 200,
}) description: 'The new, changed note',
@FullApi dto: NoteDto,
},
403,
404,
)
async updateNote( async updateNote(
@RequestUser() user: User, @RequestUser() user: User,
@RequestNote() note: Note, @RequestNote() note: Note,
@ -187,14 +164,16 @@ export class NotesController {
@UseInterceptors(GetNoteInterceptor) @UseInterceptors(GetNoteInterceptor)
@Permissions(Permission.READ) @Permissions(Permission.READ)
@UseGuards(PermissionsGuard)
@Get(':noteIdOrAlias/content') @Get(':noteIdOrAlias/content')
@ApiProduces('text/markdown') @OpenApi(
@ApiOkResponse({ {
description: 'The raw markdown content of the note', code: 200,
}) description: 'The raw markdown content of the note',
@FullApi mimeType: 'text/markdown',
@Header('content-type', 'text/markdown') },
403,
404,
)
async getNoteContent( async getNoteContent(
@RequestUser() user: User, @RequestUser() user: User,
@RequestNote() note: Note, @RequestNote() note: Note,
@ -204,13 +183,16 @@ export class NotesController {
@UseInterceptors(GetNoteInterceptor) @UseInterceptors(GetNoteInterceptor)
@Permissions(Permission.READ) @Permissions(Permission.READ)
@UseGuards(PermissionsGuard)
@Get(':noteIdOrAlias/metadata') @Get(':noteIdOrAlias/metadata')
@ApiOkResponse({ @OpenApi(
description: 'The metadata of the note', {
type: NoteMetadataDto, code: 200,
}) description: 'The metadata of the note',
@FullApi dto: NoteMetadataDto,
},
403,
404,
)
async getNoteMetadata( async getNoteMetadata(
@RequestUser() user: User, @RequestUser() user: User,
@RequestNote() note: Note, @RequestNote() note: Note,
@ -220,13 +202,16 @@ export class NotesController {
@UseInterceptors(GetNoteInterceptor) @UseInterceptors(GetNoteInterceptor)
@Permissions(Permission.OWNER) @Permissions(Permission.OWNER)
@UseGuards(PermissionsGuard)
@Put(':noteIdOrAlias/metadata/permissions') @Put(':noteIdOrAlias/metadata/permissions')
@ApiOkResponse({ @OpenApi(
description: 'The updated permissions of the note', {
type: NotePermissionsDto, code: 200,
}) description: 'The updated permissions of the note',
@FullApi dto: NotePermissionsDto,
},
403,
404,
)
async updateNotePermissions( async updateNotePermissions(
@RequestUser() user: User, @RequestUser() user: User,
@RequestNote() note: Note, @RequestNote() note: Note,
@ -239,14 +224,17 @@ export class NotesController {
@UseInterceptors(GetNoteInterceptor) @UseInterceptors(GetNoteInterceptor)
@Permissions(Permission.READ) @Permissions(Permission.READ)
@UseGuards(PermissionsGuard)
@Get(':noteIdOrAlias/revisions') @Get(':noteIdOrAlias/revisions')
@ApiOkResponse({ @OpenApi(
description: 'Revisions of the note', {
isArray: true, code: 200,
type: RevisionMetadataDto, description: 'Revisions of the note',
}) isArray: true,
@FullApi dto: RevisionMetadataDto,
},
403,
404,
)
async getNoteRevisions( async getNoteRevisions(
@RequestUser() user: User, @RequestUser() user: User,
@RequestNote() note: Note, @RequestNote() note: Note,
@ -261,13 +249,16 @@ export class NotesController {
@UseInterceptors(GetNoteInterceptor) @UseInterceptors(GetNoteInterceptor)
@Permissions(Permission.READ) @Permissions(Permission.READ)
@UseGuards(PermissionsGuard)
@Get(':noteIdOrAlias/revisions/:revisionId') @Get(':noteIdOrAlias/revisions/:revisionId')
@ApiOkResponse({ @OpenApi(
description: 'Revision of the note for the given id or alias', {
type: RevisionDto, code: 200,
}) description: 'Revision of the note for the given id or alias',
@FullApi dto: RevisionDto,
},
403,
404,
)
async getNoteRevision( async getNoteRevision(
@RequestUser() user: User, @RequestUser() user: User,
@RequestNote() note: Note, @RequestNote() note: Note,
@ -280,14 +271,13 @@ export class NotesController {
@UseInterceptors(GetNoteInterceptor) @UseInterceptors(GetNoteInterceptor)
@Permissions(Permission.READ) @Permissions(Permission.READ)
@UseGuards(PermissionsGuard)
@Get(':noteIdOrAlias/media') @Get(':noteIdOrAlias/media')
@ApiOkResponse({ @OpenApi({
code: 200,
description: 'All media uploads of the note', description: 'All media uploads of the note',
isArray: true, isArray: true,
type: MediaUploadDto, dto: MediaUploadDto,
}) })
@ApiUnauthorizedResponse({ description: unauthorizedDescription })
async getNotesMedia( async getNotesMedia(
@RequestUser() user: User, @RequestUser() user: User,
@RequestNote() note: Note, @RequestNote() note: Note,

View file

@ -1,20 +0,0 @@
/*
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
import { applyDecorators } from '@nestjs/common';
import {
ApiForbiddenResponse,
ApiNotFoundResponse,
ApiUnauthorizedResponse,
} from '@nestjs/swagger';
import { forbiddenDescription, notFoundDescription } from './descriptions';
// eslint-disable-next-line @typescript-eslint/naming-convention
export const FullApi = applyDecorators(
ApiForbiddenResponse({ description: forbiddenDescription }),
ApiNotFoundResponse({ description: notFoundDescription }),
ApiUnauthorizedResponse({ description: forbiddenDescription }),
);