From 0394679134b5ccc29480094968c706dd3616ce8e Mon Sep 17 00:00:00 2001 From: David Mehren Date: Sun, 20 Feb 2022 22:18:51 +0100 Subject: [PATCH] feat(user-info-dto): split email into separate DTO The email address should only be available in /me routes. This commit splits the email address into a new FullUserInfoDto. Signed-off-by: David Mehren --- src/api/private/me/me.controller.ts | 7 ++++--- src/api/public/me/me.controller.ts | 8 ++++---- src/users/user-info.dto.ts | 6 ++++++ src/users/users.service.spec.ts | 12 ++++++++++++ src/users/users.service.ts | 15 ++++++++++++++- test/private-api/me.e2e-spec.ts | 6 +++--- test/public-api/me.e2e-spec.ts | 2 +- 7 files changed, 44 insertions(+), 12 deletions(-) diff --git a/src/api/private/me/me.controller.ts b/src/api/private/me/me.controller.ts index eff71fb0b..9a93bff17 100644 --- a/src/api/private/me/me.controller.ts +++ b/src/api/private/me/me.controller.ts @@ -10,7 +10,7 @@ import { SessionGuard } from '../../../identity/session.guard'; import { ConsoleLoggerService } from '../../../logger/console-logger.service'; import { MediaUploadDto } from '../../../media/media-upload.dto'; import { MediaService } from '../../../media/media.service'; -import { UserInfoDto } from '../../../users/user-info.dto'; +import { FullUserInfoDto } from '../../../users/user-info.dto'; import { User } from '../../../users/user.entity'; import { UsersService } from '../../../users/users.service'; import { OpenApi } from '../../utils/openapi.decorator'; @@ -28,10 +28,11 @@ export class MeController { ) { this.logger.setContext(MeController.name); } + @Get() @OpenApi(200) - getMe(@RequestUser() user: User): UserInfoDto { - return this.userService.toUserDto(user); + getMe(@RequestUser() user: User): FullUserInfoDto { + return this.userService.toFullUserDto(user); } @Get('media') diff --git a/src/api/public/me/me.controller.ts b/src/api/public/me/me.controller.ts index 1b42167ef..27d5cfb52 100644 --- a/src/api/public/me/me.controller.ts +++ b/src/api/public/me/me.controller.ts @@ -24,7 +24,7 @@ import { MediaService } from '../../../media/media.service'; import { NoteMetadataDto } from '../../../notes/note-metadata.dto'; import { Note } from '../../../notes/note.entity'; import { NotesService } from '../../../notes/notes.service'; -import { UserInfoDto } from '../../../users/user-info.dto'; +import { FullUserInfoDto } from '../../../users/user-info.dto'; import { User } from '../../../users/user.entity'; import { UsersService } from '../../../users/users.service'; import { GetNoteInterceptor } from '../../utils/get-note.interceptor'; @@ -52,10 +52,10 @@ export class MeController { @OpenApi({ code: 200, description: 'The user information', - dto: UserInfoDto, + dto: FullUserInfoDto, }) - getMe(@RequestUser() user: User): UserInfoDto { - return this.usersService.toUserDto(user); + getMe(@RequestUser() user: User): FullUserInfoDto { + return this.usersService.toFullUserDto(user); } @Get('history') diff --git a/src/users/user-info.dto.ts b/src/users/user-info.dto.ts index 5fc2eb0db..882a6d86c 100644 --- a/src/users/user-info.dto.ts +++ b/src/users/user-info.dto.ts @@ -34,7 +34,13 @@ export class UserInfoDto extends BaseDto { }) @IsString() photo: string; +} +/** + * This DTO contains all attributes of the standard UserInfoDto + * in addition to the email address. + */ +export class FullUserInfoDto extends UserInfoDto { /** * Email address of the user * @example "john.smith@example.com" diff --git a/src/users/users.service.spec.ts b/src/users/users.service.spec.ts index 693187e74..a3a723b85 100644 --- a/src/users/users.service.spec.ts +++ b/src/users/users.service.spec.ts @@ -148,6 +148,18 @@ describe('UsersService', () => { expect(userDto.username).toEqual(username); expect(userDto.displayName).toEqual(displayname); expect(userDto.photo).toEqual(''); + }); + }); + + describe('toFullUserDto', () => { + const username = 'hardcoded'; + const displayname = 'Testy'; + const user = User.create(username, displayname) as User; + it('works if a user is provided', () => { + const userDto = service.toFullUserDto(user); + expect(userDto.username).toEqual(username); + expect(userDto.displayName).toEqual(displayname); + expect(userDto.photo).toEqual(''); expect(userDto.email).toEqual(''); }); }); diff --git a/src/users/users.service.ts b/src/users/users.service.ts index 16fb5551f..140388b91 100644 --- a/src/users/users.service.ts +++ b/src/users/users.service.ts @@ -9,7 +9,7 @@ import { Repository } from 'typeorm'; import { AlreadyInDBError, NotInDBError } from '../errors/errors'; import { ConsoleLoggerService } from '../logger/console-logger.service'; -import { UserInfoDto } from './user-info.dto'; +import { FullUserInfoDto, UserInfoDto } from './user-info.dto'; import { UserRelationEnum } from './user-relation.enum'; import { User } from './user.entity'; @@ -111,6 +111,19 @@ export class UsersService { * @return {(UserInfoDto)} the built UserInfoDto */ toUserDto(user: User): UserInfoDto { + return { + username: user.username, + displayName: user.displayName, + photo: this.getPhotoUrl(user), + }; + } + + /** + * Build FullUserInfoDto from a user. + * @param {User=} user - the user to use + * @return {(UserInfoDto)} the built FullUserInfoDto + */ + toFullUserDto(user: User): FullUserInfoDto { return { username: user.username, displayName: user.displayName, diff --git a/test/private-api/me.e2e-spec.ts b/test/private-api/me.e2e-spec.ts index a4d42a66a..5a7a73d92 100644 --- a/test/private-api/me.e2e-spec.ts +++ b/test/private-api/me.e2e-spec.ts @@ -9,7 +9,7 @@ import request from 'supertest'; import { AuthConfig } from '../../src/config/auth.config'; import { NotInDBError } from '../../src/errors/errors'; import { Note } from '../../src/notes/note.entity'; -import { UserInfoDto } from '../../src/users/user-info.dto'; +import { FullUserInfoDto } from '../../src/users/user-info.dto'; import { User } from '../../src/users/user.entity'; import { setupSessionMiddleware } from '../../src/utils/session'; import { TestSetup, TestSetupBuilder } from '../test-setup'; @@ -50,12 +50,12 @@ describe('Me', () => { }); it('GET /me', async () => { - const userInfo = testSetup.userService.toUserDto(user); + const userInfo = testSetup.userService.toFullUserDto(user); const response = await agent .get('/api/private/me') .expect('Content-Type', /json/) .expect(200); - const gotUser = response.body as UserInfoDto; + const gotUser = response.body as FullUserInfoDto; expect(gotUser).toEqual(userInfo); }); diff --git a/test/public-api/me.e2e-spec.ts b/test/public-api/me.e2e-spec.ts index e0e5f312e..13e5c8147 100644 --- a/test/public-api/me.e2e-spec.ts +++ b/test/public-api/me.e2e-spec.ts @@ -32,7 +32,7 @@ describe('Me', () => { }); it(`GET /me`, async () => { - const userInfo = testSetup.userService.toUserDto(user); + const userInfo = testSetup.userService.toFullUserDto(user); const response = await request(testSetup.app.getHttpServer()) .get('/api/v2/me') .expect('Content-Type', /json/)