Skip to content

Commit 34228b8

Browse files
committed
refactor: segregate user validation a single function, taking out the responsibility from the services
1 parent 20ca22d commit 34228b8

File tree

6 files changed

+46
-37
lines changed

6 files changed

+46
-37
lines changed

server/src/GetRequestUser.ts

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1-
import { ExecutionContext, createParamDecorator } from '@nestjs/common';
1+
import {
2+
ExecutionContext,
3+
HttpException,
4+
HttpStatus,
5+
createParamDecorator,
6+
} from '@nestjs/common';
27

38
import { UserDocument } from './user/entity/user.entity';
49

@@ -10,3 +15,18 @@ export const GetRequestToken = createParamDecorator(
1015
return user;
1116
},
1217
);
18+
19+
export const validateUser = (user: UserDocument | null) => {
20+
if (!user) {
21+
throw new HttpException(
22+
{
23+
error: {
24+
user: 'User not found',
25+
},
26+
},
27+
HttpStatus.UNAUTHORIZED,
28+
);
29+
}
30+
31+
return user;
32+
};

server/src/song/my-songs/my-songs.controller.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { ApiBearerAuth, ApiOperation } from '@nestjs/swagger';
44
import { PageQueryDTO } from '@shared/validation/common/dto/PageQuery.dto';
55
import { SongPageDto } from '@shared/validation/song/dto/SongPageDto';
66

7-
import { GetRequestToken } from '@server/GetRequestUser';
7+
import { GetRequestToken, validateUser } from '@server/GetRequestUser';
88
import { UserDocument } from '@server/user/entity/user.entity';
99

1010
import { SongService } from '../song.service';
@@ -24,6 +24,7 @@ export class MySongsController {
2424
@Query() query: PageQueryDTO,
2525
@GetRequestToken() user: UserDocument | null,
2626
): Promise<SongPageDto> {
27+
user = validateUser(user);
2728
return await this.songService.getMySongsPage({
2829
query,
2930
user,

server/src/song/song.controller.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ import { UploadSongResponseDto } from '@shared/validation/song/dto/UploadSongRes
3636
import type { Response } from 'express';
3737

3838
import { FileService } from '@server/file/file.service';
39-
import { GetRequestToken } from '@server/GetRequestUser';
39+
import { GetRequestToken, validateUser } from '@server/GetRequestUser';
4040
import { UserDocument } from '@server/user/entity/user.entity';
4141

4242
import { SongService } from './song.service';
@@ -80,6 +80,7 @@ export class SongController {
8080
@Param('id') id: string,
8181
@GetRequestToken() user: UserDocument | null,
8282
): Promise<SongViewDto> {
83+
user = validateUser(user);
8384
return await this.songService.getSong(id, user);
8485
}
8586

@@ -91,6 +92,7 @@ export class SongController {
9192
@Param('id') id: string,
9293
@GetRequestToken() user: UserDocument | null,
9394
): Promise<UploadSongDto> {
95+
user = validateUser(user);
9496
return await this.songService.getSongEdit(id, user);
9597
}
9698

@@ -107,9 +109,9 @@ export class SongController {
107109
@Req() req: RawBodyRequest<Request>,
108110
@GetRequestToken() user: UserDocument | null,
109111
): Promise<UploadSongResponseDto> {
112+
user = validateUser(user);
110113
//TODO: Fix this weird type casting and raw body access
111114
const body = req.body as unknown as UploadSongDto;
112-
113115
return await this.songService.patchSong(id, body, user);
114116
}
115117

@@ -128,6 +130,7 @@ export class SongController {
128130
'Access-Control-Expose-Headers': 'Content-Disposition',
129131
});
130132

133+
user = validateUser(user);
131134
const url = await this.songService.getSongDownloadUrl(id, user, src, false);
132135
res.redirect(HttpStatus.FOUND, url);
133136
}
@@ -139,6 +142,8 @@ export class SongController {
139142
@GetRequestToken() user: UserDocument | null,
140143
@Headers('src') src: string,
141144
): Promise<string> {
145+
user = validateUser(user);
146+
142147
if (src != 'downloadButton') {
143148
throw new UnauthorizedException('Invalid source');
144149
}
@@ -161,6 +166,7 @@ export class SongController {
161166
@Param('id') id: string,
162167
@GetRequestToken() user: UserDocument | null,
163168
): Promise<void> {
169+
user = validateUser(user);
164170
await this.songService.deleteSong(id, user);
165171
}
166172

@@ -181,6 +187,7 @@ export class SongController {
181187
@Body() body: UploadSongDto,
182188
@GetRequestToken() user: UserDocument | null,
183189
): Promise<UploadSongResponseDto> {
190+
user = validateUser(user);
184191
return await this.songService.uploadSong({ body, file, user });
185192
}
186193
}

server/src/song/song.service.ts

Lines changed: 11 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -40,32 +40,15 @@ export class SongService {
4040
private songUploadService: SongUploadService,
4141
) {}
4242

43-
private isUserValid(user: UserDocument | null) {
44-
if (!user) {
45-
throw new HttpException(
46-
{
47-
error: {
48-
user: 'User not found',
49-
},
50-
},
51-
HttpStatus.UNAUTHORIZED,
52-
);
53-
}
54-
}
55-
5643
public async uploadSong({
5744
file,
5845
user,
5946
body,
6047
}: {
6148
body: UploadSongDto;
6249
file: Express.Multer.File;
63-
user: UserDocument | null;
50+
user: UserDocument;
6451
}): Promise<UploadSongResponseDto> {
65-
// Is user valid?
66-
this.isUserValid(user);
67-
user = user as UserDocument;
68-
6952
const song = await this.songUploadService.processUploadedSong({
7053
file,
7154
user,
@@ -86,7 +69,7 @@ export class SongService {
8669

8770
public async deleteSong(
8871
publicId: string,
89-
user: UserDocument | null,
72+
user: UserDocument,
9073
): Promise<UploadSongResponseDto> {
9174
const foundSong = await this.songModel
9275
.findOne({ publicId: publicId })
@@ -115,7 +98,7 @@ export class SongService {
11598
public async patchSong(
11699
publicId: string,
117100
body: UploadSongDto,
118-
user: UserDocument | null,
101+
user: UserDocument,
119102
): Promise<UploadSongResponseDto> {
120103
const foundSong = (await this.songModel
121104
.findOne({
@@ -258,7 +241,7 @@ export class SongService {
258241

259242
public async getSong(
260243
publicId: string,
261-
user: UserDocument | null,
244+
user: UserDocument,
262245
): Promise<SongViewDto> {
263246
const foundSong = await this.songModel
264247
.findOne({ publicId: publicId })
@@ -289,7 +272,7 @@ export class SongService {
289272
// TODO: service should not handle HTTP -> https://www.reddit.com/r/node/comments/uoicw1/should_i_return_status_code_from_service_layer/
290273
public async getSongDownloadUrl(
291274
publicId: string,
292-
user: UserDocument | null,
275+
user: UserDocument,
293276
src?: string,
294277
packed: boolean = false,
295278
): Promise<string> {
@@ -339,16 +322,13 @@ export class SongService {
339322
}
340323
}
341324

342-
public async getMySongsPage(arg0: {
325+
public async getMySongsPage({
326+
query,
327+
user,
328+
}: {
343329
query: PageQueryDTO;
344-
user: UserDocument | null;
330+
user: UserDocument;
345331
}): Promise<SongPageDto> {
346-
const { query, user } = arg0;
347-
348-
if (!user) {
349-
throw new HttpException('User not found', HttpStatus.UNAUTHORIZED);
350-
}
351-
352332
const page = parseInt(query.page?.toString() ?? '1');
353333
const limit = parseInt(query.limit?.toString() ?? '10');
354334
const order = query.order ? query.order : false;
@@ -383,7 +363,7 @@ export class SongService {
383363

384364
public async getSongEdit(
385365
publicId: string,
386-
user: UserDocument | null,
366+
user: UserDocument,
387367
): Promise<UploadSongDto> {
388368
const foundSong = await this.songModel
389369
.findOne({ publicId: publicId })

server/src/user/user.controller.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { ApiBearerAuth, ApiOperation, ApiTags } from '@nestjs/swagger';
33
import { PageQueryDTO } from '@shared/validation/common/dto/PageQuery.dto';
44
import { GetUser } from '@shared/validation/user/dto/GetUser.dto';
55

6-
import { GetRequestToken } from '@server/GetRequestUser';
6+
import { GetRequestToken, validateUser } from '@server/GetRequestUser';
77

88
import { UserDocument } from './entity/user.entity';
99
import { UserService } from './user.service';
@@ -34,6 +34,7 @@ export class UserController {
3434
@ApiBearerAuth()
3535
@ApiOperation({ summary: 'Get the token owner data' })
3636
async getMe(@GetRequestToken() user: UserDocument | null) {
37+
user = validateUser(user);
3738
return await this.userService.getSelfUserData(user);
3839
}
3940
}

server/src/user/user.service.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ export class UserService {
7979
return hydratedUser;
8080
}
8181

82-
public async getSelfUserData(user: UserDocument | null) {
82+
public async getSelfUserData(user: UserDocument) {
8383
if (!user)
8484
throw new HttpException('not logged in', HttpStatus.UNAUTHORIZED);
8585
const usedData = await this.findByID(user._id.toString());

0 commit comments

Comments
 (0)