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 <git@herrmehren.de>
This commit is contained in:
David Mehren 2022-02-20 22:18:51 +01:00
parent a7edf00ebc
commit 0394679134
7 changed files with 44 additions and 12 deletions

View file

@ -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')

View file

@ -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')

View file

@ -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"

View file

@ -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('');
});
});

View file

@ -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,

View file

@ -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);
});

View file

@ -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/)