Skip to content

Commit a3138b9

Browse files
authored
Merge pull request #10 from wafflestudio/Feature/#9
Modify entities to conform to strict rules
2 parents 2d47b8a + 425a26e commit a3138b9

19 files changed

+146
-103
lines changed

src/app.module.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import {
1616
UserTag,
1717
} from './department/department.entity';
1818

19-
const ENV: string = process.env.NODE_ENV;
19+
const ENV: string | undefined = process.env.NODE_ENV;
2020

2121
@Module({
2222
imports: [
@@ -27,7 +27,7 @@ const ENV: string = process.env.NODE_ENV;
2727
TypeOrmModule.forRoot({
2828
type: 'mysql',
2929
host: process.env.DATABASE_HOST,
30-
port: +process.env.DATABASE_PORT,
30+
port: +(process.env.DATABASE_PORT ?? 3306),
3131
username: process.env.DATABASE_USER,
3232
password: process.env.DATABASE_PASSWORD,
3333
database: process.env.DATABASE_DBNAME,

src/auth/auth.service.ts

+12-5
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Injectable } from '@nestjs/common';
1+
import { Injectable, UnauthorizedException } from '@nestjs/common';
22
import { JwtService } from '@nestjs/jwt';
33
import * as bcrypt from 'bcrypt';
44
import { User } from '../user/user.entity';
@@ -8,15 +8,20 @@ import { Payload } from '../types/custom-type';
88
export class AuthService {
99
constructor(private jwtService: JwtService) {}
1010

11-
async validateUser(username: string, password: string): Promise<User> {
11+
async validateUser(
12+
username: string,
13+
password: string,
14+
): Promise<User | undefined> {
1215
const user = await User.findOne({ username });
1316
if (user && (await bcrypt.compare(password, user.password))) {
1417
return user;
1518
}
16-
return null;
19+
return undefined;
1720
}
1821

19-
async login(user: User): Promise<User> {
22+
async login(user: User | undefined): Promise<User> {
23+
if (!user) throw new UnauthorizedException();
24+
2025
const payload: Payload = { username: user.username, id: user.id };
2126

2227
const accessToken = this.jwtService.sign(payload, {
@@ -28,10 +33,12 @@ export class AuthService {
2833
});
2934
user.refreshToken = await bcrypt.hash(
3035
refreshToken,
31-
+process.env.SALT_ROUND,
36+
+process.env.SALT_ROUND!,
3237
);
3338
await User.save(user);
3439
user = await User.findOneWithKeyword({ id: user.id });
40+
41+
if (!user) throw new UnauthorizedException();
3542
user.access_token = accessToken;
3643
user.refresh_token = refreshToken;
3744

src/auth/jwt-access.strategy.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ export class JwtAccessStrategy extends PassportStrategy(
1919
}
2020

2121
async validate(payload: Payload): Promise<User> {
22-
const user: User = await User.findOne({ id: payload.id });
22+
const user: User | undefined = await User.findOne({ id: payload.id });
2323
if (!user) throw new UnauthorizedException();
2424
return user;
2525
}

src/auth/jwt-refresh.strategy.ts

+6-2
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,12 @@ export class JwtRefreshStrategy extends PassportStrategy(
1919
}
2020

2121
async validate(request: Request, payload: Payload): Promise<User> {
22-
const refreshToken = request.headers.authorization.replace('Bearer ', '');
23-
const user: User = await User.findOneIfRefreshTokenMatches(
22+
if (!request.headers.authorization) throw new UnauthorizedException();
23+
const refreshToken: string = request.headers.authorization.replace(
24+
'Bearer ',
25+
'',
26+
);
27+
const user: User | undefined = await User.findOneIfRefreshTokenMatches(
2428
refreshToken,
2529
payload.id,
2630
);

src/auth/local.strategy.ts

+4-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,10 @@ export class LocalStrategy extends PassportStrategy(Strategy) {
1111
}
1212

1313
async validate(username: string, password: string): Promise<User> {
14-
const user: User = await this.authService.validateUser(username, password);
14+
const user: User | undefined = await this.authService.validateUser(
15+
username,
16+
password,
17+
);
1518
if (!user) {
1619
throw new UnauthorizedException();
1720
}

src/department/department.entity.ts

+13-13
Original file line numberDiff line numberDiff line change
@@ -13,28 +13,28 @@ import { Expose, Transform } from 'class-transformer';
1313
@Entity()
1414
export class Department extends BaseEntity {
1515
@PrimaryGeneratedColumn()
16-
id: number;
16+
id!: number;
1717

1818
@Column()
19-
name: string;
19+
name!: string;
2020

2121
@OneToMany(() => Notice, (notice) => notice.department)
22-
notices: Notice[];
22+
notices!: Notice[];
2323

24-
@Transform((tags) => tags.value.map((tag) => tag.name))
24+
@Transform((tags) => tags.value.map((tag: Tag) => tag.name))
2525
@OneToMany(() => Tag, (tag) => tag.department)
26-
tags: Tag[];
26+
tags!: Tag[];
2727

2828
follow?: string[];
2929
}
3030

3131
@Entity()
3232
export class Tag extends BaseEntity {
3333
@PrimaryGeneratedColumn()
34-
id: number;
34+
id!: number;
3535

3636
@Column()
37-
name: string;
37+
name!: string;
3838

3939
@ManyToOne(() => Department, (department) => department.tags, {
4040
nullable: false,
@@ -43,16 +43,16 @@ export class Tag extends BaseEntity {
4343
department!: Department;
4444

4545
@OneToMany(() => UserTag, (userTag) => userTag.tag)
46-
userTags: UserTag[];
46+
userTags!: UserTag[];
4747

4848
@OneToMany(() => NoticeTag, (noticeTag) => noticeTag.tag)
49-
noticeTags: NoticeTag[];
49+
noticeTags!: NoticeTag[];
5050
}
5151

5252
@Entity()
5353
export class UserTag extends BaseEntity {
5454
@PrimaryGeneratedColumn()
55-
id: number;
55+
id!: number;
5656

5757
@ManyToOne(() => User, (user) => user.userTags, {
5858
nullable: false,
@@ -70,11 +70,11 @@ export class UserTag extends BaseEntity {
7070
@Entity()
7171
export class NoticeTag extends BaseEntity {
7272
@PrimaryGeneratedColumn()
73-
id: number;
73+
id!: number;
7474

7575
@ManyToOne(() => Notice, (notice) => notice.noticeTags)
76-
notice: Notice;
76+
notice!: Notice;
7777

7878
@ManyToOne(() => Tag, (tag) => tag.noticeTags)
79-
tag: Tag;
79+
tag!: Tag;
8080
}

src/department/department.init.ts

+5-2
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,17 @@ export const departmentInit = async (): Promise<void> => {
55
for (const departmentData of DEPARTMENTS) {
66
const { name, tags } = departmentData;
77

8-
let department: Department = await Department.findOne({ name });
8+
let department: Department | undefined = await Department.findOne({ name });
99
if (!department) {
1010
department = Department.create({ name });
1111
await Department.save(department);
1212
}
1313

1414
for (const tagName of tags) {
15-
let tag: Tag = await Tag.findOne({ name: tagName, department });
15+
let tag: Tag | undefined = await Tag.findOne({
16+
name: tagName,
17+
department,
18+
});
1619
if (!tag) {
1720
tag = Tag.create({ name: tagName, department });
1821
await Tag.save(tag);

src/department/department.service.ts

+14-8
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {
55
Injectable,
66
NotFoundException,
77
Req,
8+
UnauthorizedException,
89
} from '@nestjs/common';
910
import { PreFollow, UserRequest } from '../types/custom-type';
1011
import { Department, Tag, UserTag } from './department.entity';
@@ -33,7 +34,7 @@ export class DepartmentService {
3334
@Req() req: UserRequest,
3435
id: number,
3536
): Promise<Department> {
36-
const department: Department = await Department.findOne(id, {
37+
const department: Department | undefined = await Department.findOne(id, {
3738
relations: ['tags'],
3839
});
3940
if (!department) {
@@ -44,8 +45,12 @@ export class DepartmentService {
4445
return department;
4546
}
4647

47-
async getFollow(department: Department, user: User): Promise<string[]> {
48+
async getFollow(
49+
department: Department,
50+
user: User | undefined,
51+
): Promise<string[]> {
4852
user = await User.findOne(user);
53+
if (!user) throw new UnauthorizedException();
4954
const tags: Tag[] = await Tag.find({
5055
department,
5156
});
@@ -65,23 +70,24 @@ export class DepartmentService {
6570
id: number,
6671
followData: FollowDto,
6772
): Promise<PreFollow> {
68-
const department: Department = await Department.findOne(id, {
73+
const department: Department | undefined = await Department.findOne(id, {
6974
relations: ['tags'],
7075
});
7176
if (!department) {
7277
throw new NotFoundException('There is no department with the id');
7378
}
7479

75-
const tag: Tag = department.tags.find(
80+
const tag: Tag | undefined = department.tags.find(
7681
(tag) => tag.name === followData.follow,
7782
);
7883
if (!tag) {
7984
throw new BadRequestException(
8085
`There is no tag with the given name: ${followData.follow}`,
8186
);
8287
}
83-
const user: User = await User.findOne(req.user);
84-
const userTag: UserTag = await UserTag.findOne({
88+
const user: User | undefined = await User.findOne(req.user);
89+
if (!user) throw new UnauthorizedException();
90+
const userTag: UserTag | undefined = await UserTag.findOne({
8591
user,
8692
tag,
8793
});
@@ -95,7 +101,7 @@ export class DepartmentService {
95101
}
96102

97103
async createFollow(
98-
@Req() req,
104+
req: UserRequest,
99105
id: number,
100106
followData: FollowDto,
101107
): Promise<Department> {
@@ -120,7 +126,7 @@ export class DepartmentService {
120126
}
121127

122128
async deleteFollow(
123-
@Req() req,
129+
req: UserRequest,
124130
id: number,
125131
followData: FollowDto,
126132
): Promise<Department> {

src/department/dto/follow.dto.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@ import { IsString } from 'class-validator';
22

33
export class FollowDto {
44
@IsString()
5-
follow: string;
5+
follow!: string;
66
}

src/notice/notice.entity.ts

+14-14
Original file line numberDiff line numberDiff line change
@@ -12,22 +12,22 @@ import { Department, NoticeTag } from '../department/department.entity';
1212
@Entity()
1313
export class Notice extends BaseEntity {
1414
@PrimaryGeneratedColumn()
15-
id: number;
15+
id!: number;
1616

1717
@Column()
18-
title: string;
18+
title!: string;
1919

2020
@Column({ length: 10000 })
21-
content: string;
21+
content!: string;
2222

2323
@Column({ type: 'timestamp' })
24-
createdAt: Date;
24+
createdAt!: Date;
2525

2626
@Column({ default: false })
27-
isPinned: boolean;
27+
isPinned!: boolean;
2828

2929
@Column()
30-
link: string;
30+
link!: string;
3131

3232
@ManyToOne(() => Department, (department) => department.notices, {
3333
nullable: false,
@@ -36,25 +36,25 @@ export class Notice extends BaseEntity {
3636
department!: Department;
3737

3838
@OneToMany(() => UserNotice, (userNotice) => userNotice.notice)
39-
userNotices: UserNotice[];
39+
userNotices!: UserNotice[];
4040

4141
@OneToMany(() => File, (file) => file.notice)
42-
files: File[];
42+
files!: File[];
4343

4444
@OneToMany(() => NoticeTag, (noticeTag) => noticeTag.notice)
45-
noticeTags: NoticeTag[];
45+
noticeTags!: NoticeTag[];
4646
}
4747

4848
@Entity()
4949
export class File extends BaseEntity {
5050
@PrimaryGeneratedColumn()
51-
id: number;
51+
id!: number;
5252

5353
@Column()
54-
name: string;
54+
name!: string;
5555

5656
@Column()
57-
link: string;
57+
link!: string;
5858

5959
@ManyToOne(() => Notice, (notice) => notice.files, {
6060
nullable: false,
@@ -66,10 +66,10 @@ export class File extends BaseEntity {
6666
@Entity()
6767
export class UserNotice extends BaseEntity {
6868
@PrimaryGeneratedColumn()
69-
id: number;
69+
id!: number;
7070

7171
@Column()
72-
isScrapped: boolean;
72+
isScrapped!: boolean;
7373

7474
@ManyToOne(() => User, (user) => user.userNotices, {
7575
nullable: false,

src/types/custom-type.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,17 @@ import { User } from '../user/user.entity';
33
import { Department, Tag, UserTag } from '../department/department.entity';
44

55
export class Payload {
6-
username: string;
7-
id: number;
6+
username!: string;
7+
id!: number;
88
}
99

1010
export interface UserRequest extends Request {
11-
user?: User;
11+
user: User;
1212
}
1313

1414
export interface PreFollow {
1515
department: Department;
1616
tag: Tag;
1717
user: User;
18-
userTag: UserTag;
18+
userTag?: UserTag;
1919
}

src/user/dto/auth-user.dto.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,17 @@ import { NotDefinedValidator } from '../user.validator';
33

44
export class AuthDto {
55
@IsIn(['password', 'refresh_token'])
6-
grant_type: string;
6+
grant_type!: string;
77

88
@ValidateIf((o) => o.grant_type === 'refresh_token')
99
@Validate(NotDefinedValidator, {
1010
message: 'only refresh_token should be given to the header, not username',
1111
})
12-
username: string;
12+
username!: string;
1313

1414
@ValidateIf((o) => o.grant_type === 'refresh_token')
1515
@Validate(NotDefinedValidator, {
1616
message: 'only refresh_token should be given to the header, not password',
1717
})
18-
password: string;
18+
password!: string;
1919
}

0 commit comments

Comments
 (0)