From b07d6d478ca66e5a8703cc40d1cd086b92ef3ce8 Mon Sep 17 00:00:00 2001 From: Yannick Bungers Date: Sat, 30 Jan 2021 00:06:38 +0100 Subject: [PATCH 1/3] Refactoring of controllers and service interfaces DTO should only be used for sending information to and from user. Services now have methods which return normal internal objects and methods which convert them to DTOs. This conversion is done in the controlers Signed-off-by: Yannick Bungers --- src/api/public/me/me.controller.ts | 7 +- src/api/public/media/media.controller.ts | 9 +- .../monitoring/monitoring.controller.ts | 4 +- src/api/public/notes/notes.controller.ts | 87 +++++---- src/media/media-upload-url.dto.ts | 14 ++ src/media/media.service.ts | 11 +- src/notes/notes.service.ts | 168 ++++++++---------- src/revisions/revisions.service.ts | 22 ++- 8 files changed, 175 insertions(+), 147 deletions(-) create mode 100644 src/media/media-upload-url.dto.ts diff --git a/src/api/public/me/me.controller.ts b/src/api/public/me/me.controller.ts index 02e51e2af..6d35c9917 100644 --- a/src/api/public/me/me.controller.ts +++ b/src/api/public/me/me.controller.ts @@ -78,7 +78,10 @@ export class MeController { @UseGuards(TokenAuthGuard) @Get('notes') - getMyNotes(@Request() req): NoteMetadataDto[] { - return this.notesService.getUserNotes(req.user.userName); + async getMyNotes(@Request() req): Promise { + const notes = await this.notesService.getUserNotes(req.user) + return Promise.all( + notes.map(note => this.notesService.toNoteMetadataDto(note)) + ); } } diff --git a/src/api/public/media/media.controller.ts b/src/api/public/media/media.controller.ts index f8fd3bb45..0234c42db 100644 --- a/src/api/public/media/media.controller.ts +++ b/src/api/public/media/media.controller.ts @@ -29,6 +29,7 @@ import { MediaService } from '../../../media/media.service'; import { MulterFile } from '../../../media/multer-file.interface'; import { TokenAuthGuard } from '../../../auth/token-auth.guard'; import { ApiSecurity } from '@nestjs/swagger'; +import { MediaUploadUrlDto } from '../../../media/media-upload-url.dto'; @ApiSecurity('token') @Controller('media') @@ -47,7 +48,7 @@ export class MediaController { @Request() req, @UploadedFile() file: MulterFile, @Headers('HedgeDoc-Note') noteId: string, - ) { + ) : Promise { const username = req.user.userName; this.logger.debug( `Recieved filename '${file.originalname}' for note '${noteId}' from user '${username}'`, @@ -59,9 +60,7 @@ export class MediaController { username, noteId, ); - return { - link: url, - }; + return this.mediaService.toMediaUploadUrlDto(url) } catch (e) { if (e instanceof ClientError || e instanceof NotInDBError) { throw new BadRequestException(e.message); @@ -72,7 +71,7 @@ export class MediaController { @UseGuards(TokenAuthGuard) @Delete(':filename') - async deleteMedia(@Request() req, @Param('filename') filename: string) { + async deleteMedia(@Request() req, @Param('filename') filename: string) : Promise { const username = req.user.userName; try { await this.mediaService.deleteFile(filename, username); diff --git a/src/api/public/monitoring/monitoring.controller.ts b/src/api/public/monitoring/monitoring.controller.ts index f32e39701..c7cde2193 100644 --- a/src/api/public/monitoring/monitoring.controller.ts +++ b/src/api/public/monitoring/monitoring.controller.ts @@ -8,6 +8,7 @@ import { Controller, Get, UseGuards } from '@nestjs/common'; import { MonitoringService } from '../../../monitoring/monitoring.service'; import { TokenAuthGuard } from '../../../auth/token-auth.guard'; import { ApiSecurity } from '@nestjs/swagger'; +import { ServerStatusDto } from '../../../monitoring/server-status.dto'; @ApiSecurity('token') @Controller('monitoring') @@ -16,7 +17,8 @@ export class MonitoringController { @UseGuards(TokenAuthGuard) @Get() - getStatus() { + getStatus() : Promise { + // TODO: toServerStatusDto. return this.monitoringService.getServerStatus(); } diff --git a/src/api/public/notes/notes.controller.ts b/src/api/public/notes/notes.controller.ts index 5a1782eb3..159e58ef9 100644 --- a/src/api/public/notes/notes.controller.ts +++ b/src/api/public/notes/notes.controller.ts @@ -19,12 +19,16 @@ import { } from '@nestjs/common'; import { NotInDBError } from '../../../errors/errors'; import { ConsoleLoggerService } from '../../../logger/console-logger.service'; -import { NotePermissionsUpdateDto } from '../../../notes/note-permissions.dto'; +import { NotePermissionsDto, NotePermissionsUpdateDto } from '../../../notes/note-permissions.dto'; import { NotesService } from '../../../notes/notes.service'; import { RevisionsService } from '../../../revisions/revisions.service'; import { MarkdownBody } from '../../utils/markdownbody-decorator'; import { TokenAuthGuard } from '../../../auth/token-auth.guard'; import { ApiSecurity } from '@nestjs/swagger'; +import { NoteDto } from '../../../notes/note.dto'; +import { NoteMetadataDto } from '../../../notes/note-metadata.dto'; +import { RevisionMetadataDto } from '../../../revisions/revision-metadata.dto'; +import { RevisionDto } from '../../../revisions/revision.dto'; @ApiSecurity('token') @Controller('notes') @@ -39,18 +43,36 @@ export class NotesController { @UseGuards(TokenAuthGuard) @Post() - async createNote(@Request() req, @MarkdownBody() text: string) { + async createNote(@Request() req, @MarkdownBody() text: string): Promise { // ToDo: provide user for createNoteDto this.logger.debug('Got raw markdown:\n' + text); - return this.noteService.createNoteDto(text); + return this.noteService.toNoteDto( + await this.noteService.createNote(text, undefined, req.user) + ); + } + + @UseGuards(TokenAuthGuard) + @Post(':noteAlias') + async createNamedNote( + @Request() req, + @Param('noteAlias') noteAlias: string, + @MarkdownBody() text: string, + ): Promise { + // ToDo: check if user is allowed to view this note + this.logger.debug('Got raw markdown:\n' + text); + return this.noteService.toNoteDto( + await this.noteService.createNote(text, noteAlias, req.user) + ); } @UseGuards(TokenAuthGuard) @Get(':noteIdOrAlias') - async getNote(@Request() req, @Param('noteIdOrAlias') noteIdOrAlias: string) { + async getNote(@Request() req, @Param('noteIdOrAlias') noteIdOrAlias: string) : Promise { // ToDo: check if user is allowed to view this note try { - return await this.noteService.getNoteDtoByIdOrAlias(noteIdOrAlias); + return this.noteService.toNoteDto( + await this.noteService.getNoteByIdOrAlias(noteIdOrAlias) + ); } catch (e) { if (e instanceof NotInDBError) { throw new NotFoundException(e.message); @@ -59,24 +81,12 @@ export class NotesController { } } - @UseGuards(TokenAuthGuard) - @Post(':noteAlias') - async createNamedNote( - @Request() req, - @Param('noteAlias') noteAlias: string, - @MarkdownBody() text: string, - ) { - // ToDo: check if user is allowed to view this note - this.logger.debug('Got raw markdown:\n' + text); - return this.noteService.createNoteDto(text, noteAlias); - } - @UseGuards(TokenAuthGuard) @Delete(':noteIdOrAlias') async deleteNote( @Request() req, @Param('noteIdOrAlias') noteIdOrAlias: string, - ) { + ): Promise { // ToDo: check if user is allowed to delete this note this.logger.debug('Deleting note: ' + noteIdOrAlias); try { @@ -97,11 +107,13 @@ export class NotesController { @Request() req, @Param('noteIdOrAlias') noteIdOrAlias: string, @MarkdownBody() text: string, - ) { + ) : Promise { // ToDo: check if user is allowed to change this note this.logger.debug('Got raw markdown:\n' + text); try { - return await this.noteService.updateNoteByIdOrAlias(noteIdOrAlias, text); + return this.noteService.toNoteDto( + await this.noteService.updateNoteByIdOrAlias(noteIdOrAlias, text) + ); } catch (e) { if (e instanceof NotInDBError) { throw new NotFoundException(e.message); @@ -116,7 +128,7 @@ export class NotesController { async getNoteContent( @Request() req, @Param('noteIdOrAlias') noteIdOrAlias: string, - ) { + ) : Promise { // ToDo: check if user is allowed to view this notes content try { return await this.noteService.getNoteContent(noteIdOrAlias); @@ -133,10 +145,12 @@ export class NotesController { async getNoteMetadata( @Request() req, @Param('noteIdOrAlias') noteIdOrAlias: string, - ) { + ) : Promise { // ToDo: check if user is allowed to view this notes metadata try { - return await this.noteService.getNoteMetadata(noteIdOrAlias); + return this.noteService.toNoteMetadataDto( + await this.noteService.getNoteByIdOrAlias(noteIdOrAlias) + ); } catch (e) { if (e instanceof NotInDBError) { throw new NotFoundException(e.message); @@ -151,12 +165,14 @@ export class NotesController { @Request() req, @Param('noteIdOrAlias') noteIdOrAlias: string, @Body() updateDto: NotePermissionsUpdateDto, - ) { + ) : Promise { // ToDo: check if user is allowed to view this notes permissions try { - return await this.noteService.updateNotePermissions( - noteIdOrAlias, - updateDto, + return this.noteService.toNotePermissionsDto( + await this.noteService.updateNotePermissions( + noteIdOrAlias, + updateDto, + ) ); } catch (e) { if (e instanceof NotInDBError) { @@ -171,12 +187,15 @@ export class NotesController { async getNoteRevisions( @Request() req, @Param('noteIdOrAlias') noteIdOrAlias: string, - ) { + ) : Promise { // ToDo: check if user is allowed to view this notes revisions try { - return await this.revisionsService.getNoteRevisionMetadatas( + const revisions = await this.revisionsService.getAllRevisions( noteIdOrAlias, ); + return Promise.all( + revisions.map(revision => this.revisionsService.toRevisionMetadataDto(revision)) + ); } catch (e) { if (e instanceof NotInDBError) { throw new NotFoundException(e.message); @@ -191,12 +210,14 @@ export class NotesController { @Request() req, @Param('noteIdOrAlias') noteIdOrAlias: string, @Param('revisionId') revisionId: number, - ) { + ) : Promise { // ToDo: check if user is allowed to view this notes revision try { - return await this.revisionsService.getNoteRevision( - noteIdOrAlias, - revisionId, + return this.revisionsService.toRevisionDto( + await this.revisionsService.getRevision( + noteIdOrAlias, + revisionId, + ) ); } catch (e) { if (e instanceof NotInDBError) { diff --git a/src/media/media-upload-url.dto.ts b/src/media/media-upload-url.dto.ts new file mode 100644 index 000000000..c4b869894 --- /dev/null +++ b/src/media/media-upload-url.dto.ts @@ -0,0 +1,14 @@ +/* + * SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file) + * + * SPDX-License-Identifier: AGPL-3.0-only + */ + + + +import { IsString } from 'class-validator'; + +export class MediaUploadUrlDto { + @IsString() + link: string +} diff --git a/src/media/media.service.ts b/src/media/media.service.ts index 8b5dfdecb..4714281c4 100644 --- a/src/media/media.service.ts +++ b/src/media/media.service.ts @@ -18,6 +18,7 @@ import { BackendType } from './backends/backend-type.enum'; import { FilesystemBackend } from './backends/filesystem-backend'; import { MediaBackend } from './media-backend.interface'; import { MediaUpload } from './media-upload.entity'; +import { MediaUploadUrlDto } from './media-upload-url.dto'; @Injectable() export class MediaService { @@ -58,7 +59,7 @@ export class MediaService { return allowedTypes.includes(mimeType); } - public async saveFile(fileBuffer: Buffer, username: string, noteId: string) { + public async saveFile(fileBuffer: Buffer, username: string, noteId: string): Promise { this.logger.debug( `Saving file for note '${noteId}' and user '${username}'`, 'saveFile', @@ -88,7 +89,7 @@ export class MediaService { return url; } - public async deleteFile(filename: string, username: string) { + public async deleteFile(filename: string, username: string): Promise { this.logger.debug( `Deleting '${filename}' for user '${username}'`, 'deleteFile', @@ -132,4 +133,10 @@ export class MediaService { return this.moduleRef.get(FilesystemBackend); } } + + toMediaUploadUrlDto(url: string): MediaUploadUrlDto { + return { + link: url, + } + } } diff --git a/src/notes/notes.service.ts b/src/notes/notes.service.ts index 8e1f11284..b810246f4 100644 --- a/src/notes/notes.service.ts +++ b/src/notes/notes.service.ts @@ -35,48 +35,26 @@ export class NotesService { this.logger.setContext(NotesService.name); } - getUserNotes(username: string): NoteMetadataDto[] { + getUserNotes(user: User): Note[] { this.logger.warn('Using hardcoded data!'); return [ { - alias: null, - createTime: new Date(), - description: 'Very descriptive text.', - editedBy: [], id: 'foobar-barfoo', - permissions: { - owner: { - displayName: 'foo', - userName: 'fooUser', - email: 'foo@example.com', - photo: '', - }, - sharedToUsers: [], - sharedToGroups: [], - }, + alias: null, + shortid: "abc", + owner: user, + description: 'Very descriptive text.', + userPermissions: [], + groupPermissions: [], tags: [], + revisions: Promise.resolve([]), + authorColors: [], title: 'Title!', - updateTime: new Date(), - updateUser: { - displayName: 'foo', - userName: 'fooUser', - email: 'foo@example.com', - photo: '', - }, - viewCount: 42, + viewcount: 42, }, ]; } - async createNoteDto( - noteContent: string, - alias?: NoteMetadataDto['alias'], - owner?: User, - ): Promise { - const note = await this.createNote(noteContent, alias, owner); - return this.toNoteDto(note); - } - async createNote( noteContent: string, alias?: NoteMetadataDto['alias'], @@ -96,7 +74,7 @@ export class NotesService { return this.noteRepository.save(newNote); } - async getCurrentContent(note: Note) { + async getCurrentContent(note: Note): Promise { return (await this.getLatestRevision(note)).content; } @@ -108,42 +86,6 @@ export class NotesService { return this.revisionsService.getFirstRevision(note.id); } - async getMetadata(note: Note): Promise { - return { - // TODO: Convert DB UUID to base64 - id: note.id, - alias: note.alias, - title: note.title, - createTime: (await this.getFirstRevision(note)).createdAt, - description: note.description, - editedBy: note.authorColors.map( - (authorColor) => authorColor.user.userName, - ), - // TODO: Extract into method - permissions: { - owner: this.usersService.toUserDto(note.owner), - sharedToUsers: note.userPermissions.map((noteUserPermission) => ({ - user: this.usersService.toUserDto(noteUserPermission.user), - canEdit: noteUserPermission.canEdit, - })), - sharedToGroups: note.groupPermissions.map((noteGroupPermission) => ({ - group: noteGroupPermission.group, - canEdit: noteGroupPermission.canEdit, - })), - }, - tags: note.tags.map((tag) => tag.name), - updateTime: (await this.getLatestRevision(note)).createdAt, - // TODO: Get actual updateUser - updateUser: { - displayName: 'Hardcoded User', - userName: 'hardcoded', - email: 'foo@example.com', - photo: '', - }, - viewCount: 42, - }; - } - async getNoteByIdOrAlias(noteIdOrAlias: string): Promise { this.logger.debug( `Trying to find note '${noteIdOrAlias}'`, @@ -178,45 +120,47 @@ export class NotesService { return note; } - async getNoteDtoByIdOrAlias(noteIdOrAlias: string): Promise { - const note = await this.getNoteByIdOrAlias(noteIdOrAlias); - return this.toNoteDto(note); - } - async deleteNoteByIdOrAlias(noteIdOrAlias: string) { const note = await this.getNoteByIdOrAlias(noteIdOrAlias); return await this.noteRepository.remove(note); } - async updateNoteByIdOrAlias(noteIdOrAlias: string, noteContent: string) { + async updateNoteByIdOrAlias(noteIdOrAlias: string, noteContent: string): Promise { const note = await this.getNoteByIdOrAlias(noteIdOrAlias); const revisions = await note.revisions; //TODO: Calculate patch revisions.push(Revision.create(noteContent, noteContent)); note.revisions = Promise.resolve(revisions); - await this.noteRepository.save(note); - return this.toNoteDto(note); - } - - async getNoteMetadata(noteIdOrAlias: string): Promise { - const note = await this.getNoteByIdOrAlias(noteIdOrAlias); - return this.getMetadata(note); + return this.noteRepository.save(note); } updateNotePermissions( noteIdOrAlias: string, newPermissions: NotePermissionsUpdateDto, - ): NotePermissionsDto { + ): Note { this.logger.warn('Using hardcoded data!'); return { - owner: { - displayName: 'foo', - userName: 'fooUser', - email: 'foo@example.com', - photo: '', - }, - sharedToUsers: [], - sharedToGroups: [], + id: 'foobar-barfoo', + alias: null, + shortid: "abc", + owner: { + authTokens: [], + createdAt: new Date(), + displayName: 'hardcoded', + id: '1', + identities: [], + ownedNotes: [], + updatedAt: new Date(), + userName: 'Testy', + }, + description: 'Very descriptive text.', + userPermissions: [], + groupPermissions: [], + tags: [], + revisions: Promise.resolve([]), + authorColors: [], + title: 'Title!', + viewcount: 42, }; } @@ -225,10 +169,50 @@ export class NotesService { return this.getCurrentContent(note); } + async toNotePermissionsDto(note: Note): Promise { + return { + owner: this.usersService.toUserDto(note.owner), + sharedToUsers: note.userPermissions.map((noteUserPermission) => ({ + user: this.usersService.toUserDto(noteUserPermission.user), + canEdit: noteUserPermission.canEdit, + })), + sharedToGroups: note.groupPermissions.map((noteGroupPermission) => ({ + group: noteGroupPermission.group, + canEdit: noteGroupPermission.canEdit, + })), + } + } + + async toNoteMetadataDto(note: Note): Promise { + return { + // TODO: Convert DB UUID to base64 + id: note.id, + alias: note.alias, + title: note.title, + createTime: (await this.getFirstRevision(note)).createdAt, + description: note.description, + editedBy: note.authorColors.map( + (authorColor) => authorColor.user.userName, + ), + // TODO: Extract into method + permissions: await this.toNotePermissionsDto(note), + tags: note.tags.map((tag) => tag.name), + updateTime: (await this.getLatestRevision(note)).createdAt, + // TODO: Get actual updateUser + updateUser: { + displayName: 'Hardcoded User', + userName: 'hardcoded', + email: 'foo@example.com', + photo: '', + }, + viewCount: 42, + }; + } + async toNoteDto(note: Note): Promise { return { content: await this.getCurrentContent(note), - metadata: await this.getMetadata(note), + metadata: await this.toNoteMetadataDto(note), editedByAtPosition: [], }; } diff --git a/src/revisions/revisions.service.ts b/src/revisions/revisions.service.ts index 389fe422d..5052b0dc1 100644 --- a/src/revisions/revisions.service.ts +++ b/src/revisions/revisions.service.ts @@ -24,30 +24,28 @@ export class RevisionsService { this.logger.setContext(RevisionsService.name); } - async getNoteRevisionMetadatas( + async getAllRevisions( noteIdOrAlias: string, - ): Promise { + ): Promise { const note = await this.notesService.getNoteByIdOrAlias(noteIdOrAlias); - const revisions = await this.revisionRepository.find({ + return await this.revisionRepository.find({ where: { - note: note.id, + note: note, }, }); - return revisions.map((revision) => this.toMetadataDto(revision)); } - async getNoteRevision( + async getRevision( noteIdOrAlias: string, revisionId: number, - ): Promise { + ): Promise { const note = await this.notesService.getNoteByIdOrAlias(noteIdOrAlias); - const revision = await this.revisionRepository.findOne({ + return await this.revisionRepository.findOne({ where: { id: revisionId, note: note, }, }); - return this.toDto(revision); } getLatestRevision(noteId: string): Promise { @@ -73,7 +71,7 @@ export class RevisionsService { }); } - toMetadataDto(revision: Revision): RevisionMetadataDto { + toRevisionMetadataDto(revision: Revision): RevisionMetadataDto { return { id: revision.id, length: revision.length, @@ -81,7 +79,7 @@ export class RevisionsService { }; } - toDto(revision: Revision): RevisionDto { + toRevisionDto(revision: Revision): RevisionDto { return { id: revision.id, content: revision.content, @@ -90,7 +88,7 @@ export class RevisionsService { }; } - createRevision(content: string) { + createRevision(content: string) : Revision { // TODO: Add previous revision // TODO: Calculate patch // TODO: Save metadata From a7f35aaeec1626c1af558d9b91b7debb9f18faf1 Mon Sep 17 00:00:00 2001 From: Philip Molares Date: Sat, 30 Jan 2021 12:47:31 +0100 Subject: [PATCH 2/3] tests: Fix tests as part of the DTO Refactor Signed-off-by: Philip Molares --- src/auth/mock-auth.guard.ts | 14 ++++++++++---- test/public-api/media.e2e-spec.ts | 3 --- test/public-api/notes.e2e-spec.ts | 19 +++++++++++-------- 3 files changed, 21 insertions(+), 15 deletions(-) diff --git a/src/auth/mock-auth.guard.ts b/src/auth/mock-auth.guard.ts index 9d15bc83e..d4f1236b0 100644 --- a/src/auth/mock-auth.guard.ts +++ b/src/auth/mock-auth.guard.ts @@ -5,14 +5,20 @@ */ import { ExecutionContext, Injectable } from '@nestjs/common'; +import { UsersService } from '../users/users.service'; +import { User } from '../users/user.entity'; @Injectable() export class MockAuthGuard { - canActivate(context: ExecutionContext) { + private user: User; + constructor(private usersService: UsersService) {} + + async canActivate(context: ExecutionContext) { const req = context.switchToHttp().getRequest(); - req.user = { - userName: 'hardcoded', - }; + if (!this.user) { + this.user = await this.usersService.createUser('hardcoded', 'Testy'); + } + req.user = this.user; return true; } } diff --git a/test/public-api/media.e2e-spec.ts b/test/public-api/media.e2e-spec.ts index f4b57ebf0..26ee76d27 100644 --- a/test/public-api/media.e2e-spec.ts +++ b/test/public-api/media.e2e-spec.ts @@ -20,7 +20,6 @@ import { MediaService } from '../../src/media/media.service'; import { NotesModule } from '../../src/notes/notes.module'; import { NotesService } from '../../src/notes/notes.service'; import { PermissionsModule } from '../../src/permissions/permissions.module'; -import { UsersService } from '../../src/users/users.service'; import { AuthModule } from '../../src/auth/auth.module'; import { TokenAuthGuard } from '../../src/auth/token-auth.guard'; import { MockAuthGuard } from '../../src/auth/mock-auth.guard'; @@ -65,8 +64,6 @@ describe('Notes', () => { app.useLogger(logger); const notesService: NotesService = moduleRef.get('NotesService'); await notesService.createNote('test content', 'test_upload_media'); - const usersService: UsersService = moduleRef.get('UsersService'); - await usersService.createUser('hardcoded', 'Hard Coded'); mediaService = moduleRef.get('MediaService'); }); diff --git a/test/public-api/notes.e2e-spec.ts b/test/public-api/notes.e2e-spec.ts index bf9ca8c55..5059f3e93 100644 --- a/test/public-api/notes.e2e-spec.ts +++ b/test/public-api/notes.e2e-spec.ts @@ -20,7 +20,7 @@ import { PermissionsModule } from '../../src/permissions/permissions.module'; import { AuthModule } from '../../src/auth/auth.module'; import { TokenAuthGuard } from '../../src/auth/token-auth.guard'; import { MockAuthGuard } from '../../src/auth/mock-auth.guard'; -import { UsersService } from '../../src/users/users.service'; +import { UsersModule } from '../../src/users/users.module'; describe('Notes', () => { let app: INestApplication; @@ -46,6 +46,7 @@ describe('Notes', () => { }), LoggerModule, AuthModule, + UsersModule, ], }) .overrideGuard(TokenAuthGuard) @@ -55,8 +56,6 @@ describe('Notes', () => { app = moduleRef.createNestApplication(); await app.init(); notesService = moduleRef.get(NotesService); - const usersService: UsersService = moduleRef.get('UsersService'); - await usersService.createUser('testy', 'Testy McTestFace'); }); it(`POST /notes`, async () => { @@ -69,8 +68,9 @@ describe('Notes', () => { .expect(201); expect(response.body.metadata?.id).toBeDefined(); expect( - (await notesService.getNoteDtoByIdOrAlias(response.body.metadata.id)) - .content, + await notesService.getCurrentContent( + await notesService.getNoteByIdOrAlias(response.body.metadata.id), + ), ).toEqual(newNote); }); @@ -100,8 +100,9 @@ describe('Notes', () => { .expect(201); expect(response.body.metadata?.id).toBeDefined(); return expect( - (await notesService.getNoteDtoByIdOrAlias(response.body.metadata.id)) - .content, + await notesService.getCurrentContent( + await notesService.getNoteByIdOrAlias(response.body.metadata?.id), + ), ).toEqual(newNote); }); @@ -125,7 +126,9 @@ describe('Notes', () => { .send('New note text') .expect(200); await expect( - (await notesService.getNoteDtoByIdOrAlias('test4')).content, + await notesService.getCurrentContent( + await notesService.getNoteByIdOrAlias('test4'), + ), ).toEqual('New note text'); expect(response.body.content).toEqual('New note text'); From c2b6c6fe497731ef41881150e391ae2a78adc5e9 Mon Sep 17 00:00:00 2001 From: Yannick Bungers Date: Sat, 30 Jan 2021 18:09:00 +0100 Subject: [PATCH 3/3] Reformat code by yarn format Signed-off-by: Yannick Bungers --- src/api/public/me/me.controller.ts | 4 +- src/api/public/media/media.controller.ts | 9 ++-- .../monitoring/monitoring.controller.ts | 2 +- src/api/public/notes/notes.controller.ts | 51 ++++++++++--------- src/media/media-upload-url.dto.ts | 4 +- src/media/media.service.ts | 8 ++- src/notes/notes.service.ts | 51 ++++++++++--------- src/revisions/revisions.service.ts | 6 +-- 8 files changed, 73 insertions(+), 62 deletions(-) diff --git a/src/api/public/me/me.controller.ts b/src/api/public/me/me.controller.ts index 6d35c9917..4bbf8ccdb 100644 --- a/src/api/public/me/me.controller.ts +++ b/src/api/public/me/me.controller.ts @@ -79,9 +79,9 @@ export class MeController { @UseGuards(TokenAuthGuard) @Get('notes') async getMyNotes(@Request() req): Promise { - const notes = await this.notesService.getUserNotes(req.user) + const notes = await this.notesService.getUserNotes(req.user); return Promise.all( - notes.map(note => this.notesService.toNoteMetadataDto(note)) + notes.map((note) => this.notesService.toNoteMetadataDto(note)), ); } } diff --git a/src/api/public/media/media.controller.ts b/src/api/public/media/media.controller.ts index 0234c42db..c1c211063 100644 --- a/src/api/public/media/media.controller.ts +++ b/src/api/public/media/media.controller.ts @@ -48,7 +48,7 @@ export class MediaController { @Request() req, @UploadedFile() file: MulterFile, @Headers('HedgeDoc-Note') noteId: string, - ) : Promise { + ): Promise { const username = req.user.userName; this.logger.debug( `Recieved filename '${file.originalname}' for note '${noteId}' from user '${username}'`, @@ -60,7 +60,7 @@ export class MediaController { username, noteId, ); - return this.mediaService.toMediaUploadUrlDto(url) + return this.mediaService.toMediaUploadUrlDto(url); } catch (e) { if (e instanceof ClientError || e instanceof NotInDBError) { throw new BadRequestException(e.message); @@ -71,7 +71,10 @@ export class MediaController { @UseGuards(TokenAuthGuard) @Delete(':filename') - async deleteMedia(@Request() req, @Param('filename') filename: string) : Promise { + async deleteMedia( + @Request() req, + @Param('filename') filename: string, + ): Promise { const username = req.user.userName; try { await this.mediaService.deleteFile(filename, username); diff --git a/src/api/public/monitoring/monitoring.controller.ts b/src/api/public/monitoring/monitoring.controller.ts index c7cde2193..d90b81117 100644 --- a/src/api/public/monitoring/monitoring.controller.ts +++ b/src/api/public/monitoring/monitoring.controller.ts @@ -17,7 +17,7 @@ export class MonitoringController { @UseGuards(TokenAuthGuard) @Get() - getStatus() : Promise { + getStatus(): Promise { // TODO: toServerStatusDto. return this.monitoringService.getServerStatus(); } diff --git a/src/api/public/notes/notes.controller.ts b/src/api/public/notes/notes.controller.ts index 159e58ef9..4478356d5 100644 --- a/src/api/public/notes/notes.controller.ts +++ b/src/api/public/notes/notes.controller.ts @@ -19,7 +19,10 @@ import { } from '@nestjs/common'; import { NotInDBError } from '../../../errors/errors'; import { ConsoleLoggerService } from '../../../logger/console-logger.service'; -import { NotePermissionsDto, NotePermissionsUpdateDto } from '../../../notes/note-permissions.dto'; +import { + NotePermissionsDto, + NotePermissionsUpdateDto, +} from '../../../notes/note-permissions.dto'; import { NotesService } from '../../../notes/notes.service'; import { RevisionsService } from '../../../revisions/revisions.service'; import { MarkdownBody } from '../../utils/markdownbody-decorator'; @@ -43,11 +46,14 @@ export class NotesController { @UseGuards(TokenAuthGuard) @Post() - async createNote(@Request() req, @MarkdownBody() text: string): Promise { + async createNote( + @Request() req, + @MarkdownBody() text: string, + ): Promise { // ToDo: provide user for createNoteDto this.logger.debug('Got raw markdown:\n' + text); return this.noteService.toNoteDto( - await this.noteService.createNote(text, undefined, req.user) + await this.noteService.createNote(text, undefined, req.user), ); } @@ -61,17 +67,20 @@ export class NotesController { // ToDo: check if user is allowed to view this note this.logger.debug('Got raw markdown:\n' + text); return this.noteService.toNoteDto( - await this.noteService.createNote(text, noteAlias, req.user) + await this.noteService.createNote(text, noteAlias, req.user), ); } @UseGuards(TokenAuthGuard) @Get(':noteIdOrAlias') - async getNote(@Request() req, @Param('noteIdOrAlias') noteIdOrAlias: string) : Promise { + async getNote( + @Request() req, + @Param('noteIdOrAlias') noteIdOrAlias: string, + ): Promise { // ToDo: check if user is allowed to view this note try { return this.noteService.toNoteDto( - await this.noteService.getNoteByIdOrAlias(noteIdOrAlias) + await this.noteService.getNoteByIdOrAlias(noteIdOrAlias), ); } catch (e) { if (e instanceof NotInDBError) { @@ -107,12 +116,12 @@ export class NotesController { @Request() req, @Param('noteIdOrAlias') noteIdOrAlias: string, @MarkdownBody() text: string, - ) : Promise { + ): Promise { // ToDo: check if user is allowed to change this note this.logger.debug('Got raw markdown:\n' + text); try { return this.noteService.toNoteDto( - await this.noteService.updateNoteByIdOrAlias(noteIdOrAlias, text) + await this.noteService.updateNoteByIdOrAlias(noteIdOrAlias, text), ); } catch (e) { if (e instanceof NotInDBError) { @@ -128,7 +137,7 @@ export class NotesController { async getNoteContent( @Request() req, @Param('noteIdOrAlias') noteIdOrAlias: string, - ) : Promise { + ): Promise { // ToDo: check if user is allowed to view this notes content try { return await this.noteService.getNoteContent(noteIdOrAlias); @@ -145,11 +154,11 @@ export class NotesController { async getNoteMetadata( @Request() req, @Param('noteIdOrAlias') noteIdOrAlias: string, - ) : Promise { + ): Promise { // ToDo: check if user is allowed to view this notes metadata try { return this.noteService.toNoteMetadataDto( - await this.noteService.getNoteByIdOrAlias(noteIdOrAlias) + await this.noteService.getNoteByIdOrAlias(noteIdOrAlias), ); } catch (e) { if (e instanceof NotInDBError) { @@ -165,14 +174,11 @@ export class NotesController { @Request() req, @Param('noteIdOrAlias') noteIdOrAlias: string, @Body() updateDto: NotePermissionsUpdateDto, - ) : Promise { + ): Promise { // ToDo: check if user is allowed to view this notes permissions try { return this.noteService.toNotePermissionsDto( - await this.noteService.updateNotePermissions( - noteIdOrAlias, - updateDto, - ) + await this.noteService.updateNotePermissions(noteIdOrAlias, updateDto), ); } catch (e) { if (e instanceof NotInDBError) { @@ -187,14 +193,16 @@ export class NotesController { async getNoteRevisions( @Request() req, @Param('noteIdOrAlias') noteIdOrAlias: string, - ) : Promise { + ): Promise { // ToDo: check if user is allowed to view this notes revisions try { const revisions = await this.revisionsService.getAllRevisions( noteIdOrAlias, ); return Promise.all( - revisions.map(revision => this.revisionsService.toRevisionMetadataDto(revision)) + revisions.map((revision) => + this.revisionsService.toRevisionMetadataDto(revision), + ), ); } catch (e) { if (e instanceof NotInDBError) { @@ -210,14 +218,11 @@ export class NotesController { @Request() req, @Param('noteIdOrAlias') noteIdOrAlias: string, @Param('revisionId') revisionId: number, - ) : Promise { + ): Promise { // ToDo: check if user is allowed to view this notes revision try { return this.revisionsService.toRevisionDto( - await this.revisionsService.getRevision( - noteIdOrAlias, - revisionId, - ) + await this.revisionsService.getRevision(noteIdOrAlias, revisionId), ); } catch (e) { if (e instanceof NotInDBError) { diff --git a/src/media/media-upload-url.dto.ts b/src/media/media-upload-url.dto.ts index c4b869894..9e9c9296c 100644 --- a/src/media/media-upload-url.dto.ts +++ b/src/media/media-upload-url.dto.ts @@ -4,11 +4,9 @@ * SPDX-License-Identifier: AGPL-3.0-only */ - - import { IsString } from 'class-validator'; export class MediaUploadUrlDto { @IsString() - link: string + link: string; } diff --git a/src/media/media.service.ts b/src/media/media.service.ts index 4714281c4..b22aa8aab 100644 --- a/src/media/media.service.ts +++ b/src/media/media.service.ts @@ -59,7 +59,11 @@ export class MediaService { return allowedTypes.includes(mimeType); } - public async saveFile(fileBuffer: Buffer, username: string, noteId: string): Promise { + public async saveFile( + fileBuffer: Buffer, + username: string, + noteId: string, + ): Promise { this.logger.debug( `Saving file for note '${noteId}' and user '${username}'`, 'saveFile', @@ -137,6 +141,6 @@ export class MediaService { toMediaUploadUrlDto(url: string): MediaUploadUrlDto { return { link: url, - } + }; } } diff --git a/src/notes/notes.service.ts b/src/notes/notes.service.ts index b810246f4..0e3998987 100644 --- a/src/notes/notes.service.ts +++ b/src/notes/notes.service.ts @@ -41,7 +41,7 @@ export class NotesService { { id: 'foobar-barfoo', alias: null, - shortid: "abc", + shortid: 'abc', owner: user, description: 'Very descriptive text.', userPermissions: [], @@ -125,7 +125,10 @@ export class NotesService { return await this.noteRepository.remove(note); } - async updateNoteByIdOrAlias(noteIdOrAlias: string, noteContent: string): Promise { + async updateNoteByIdOrAlias( + noteIdOrAlias: string, + noteContent: string, + ): Promise { const note = await this.getNoteByIdOrAlias(noteIdOrAlias); const revisions = await note.revisions; //TODO: Calculate patch @@ -140,27 +143,27 @@ export class NotesService { ): Note { this.logger.warn('Using hardcoded data!'); return { - id: 'foobar-barfoo', - alias: null, - shortid: "abc", - owner: { - authTokens: [], - createdAt: new Date(), - displayName: 'hardcoded', - id: '1', - identities: [], - ownedNotes: [], - updatedAt: new Date(), - userName: 'Testy', - }, - description: 'Very descriptive text.', - userPermissions: [], - groupPermissions: [], - tags: [], - revisions: Promise.resolve([]), - authorColors: [], - title: 'Title!', - viewcount: 42, + id: 'foobar-barfoo', + alias: null, + shortid: 'abc', + owner: { + authTokens: [], + createdAt: new Date(), + displayName: 'hardcoded', + id: '1', + identities: [], + ownedNotes: [], + updatedAt: new Date(), + userName: 'Testy', + }, + description: 'Very descriptive text.', + userPermissions: [], + groupPermissions: [], + tags: [], + revisions: Promise.resolve([]), + authorColors: [], + title: 'Title!', + viewcount: 42, }; } @@ -180,7 +183,7 @@ export class NotesService { group: noteGroupPermission.group, canEdit: noteGroupPermission.canEdit, })), - } + }; } async toNoteMetadataDto(note: Note): Promise { diff --git a/src/revisions/revisions.service.ts b/src/revisions/revisions.service.ts index 5052b0dc1..a3735337d 100644 --- a/src/revisions/revisions.service.ts +++ b/src/revisions/revisions.service.ts @@ -24,9 +24,7 @@ export class RevisionsService { this.logger.setContext(RevisionsService.name); } - async getAllRevisions( - noteIdOrAlias: string, - ): Promise { + async getAllRevisions(noteIdOrAlias: string): Promise { const note = await this.notesService.getNoteByIdOrAlias(noteIdOrAlias); return await this.revisionRepository.find({ where: { @@ -88,7 +86,7 @@ export class RevisionsService { }; } - createRevision(content: string) : Revision { + createRevision(content: string): Revision { // TODO: Add previous revision // TODO: Calculate patch // TODO: Save metadata