-
Notifications
You must be signed in to change notification settings - Fork 22
Expand file tree
/
Copy pathauth.service.ts
More file actions
97 lines (79 loc) · 2.7 KB
/
auth.service.ts
File metadata and controls
97 lines (79 loc) · 2.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
import { Injectable } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { JwtService } from '@nestjs/jwt';
import * as bcrypt from 'bcrypt';
import { SignInInput, SignUpInput } from 'src/auth/inputs/auth.input';
import { CustomConflictException } from 'src/common/exceptions';
import { EnvironmentVariables } from 'src/common/helper/env.validation';
import { UtilService } from 'src/common/util/util.service';
import { User } from 'src/user/entities/user.entity';
import { UserService } from '../user/user.service';
import { JwtWithUser } from './entities/auth._entity';
@Injectable()
export class AuthService {
constructor(
private readonly userService: UserService,
private readonly jwtService: JwtService,
private readonly configService: ConfigService<EnvironmentVariables>,
private readonly utilService: UtilService,
) {}
private async generateRefreshToken(userId: string) {
const refreshToken = this.jwtService.sign(
{ id: userId },
{
secret: this.configService.get('JWT_REFRESH_TOKEN_PRIVATE_KEY'),
expiresIn: '7d',
},
);
await this.userService.update(userId, { refreshToken });
return refreshToken;
}
async verifyRefreshToken(
userId: string,
refreshToken: string,
): Promise<User> {
try {
this.jwtService.verify(refreshToken, {
secret: this.configService.get('JWT_REFRESH_TOKEN_PRIVATE_KEY'),
});
return this.userService.getOne({ where: { id: userId, refreshToken } });
} catch (err) {
if (err.message === 'jwt expired') {
this.userService.update(userId, { refreshToken: null });
}
}
}
generateAccessToken(user: User, refreshToken: string) {
return this.jwtService.sign({
...this.utilService.pick(user, ['id', 'role']),
refreshToken,
});
}
async signUp(input: SignUpInput): Promise<JwtWithUser> {
const doesExist = await this.userService.getOne({
where: { username: input.username },
});
if (doesExist) {
throw new CustomConflictException({ property: 'username' });
}
const user = await this.userService.create({ ...input, role: 'user' });
return this.signIn(user);
}
async signIn(user: User) {
const refreshToken = await this.generateRefreshToken(user.id);
const jwt = this.generateAccessToken(user, refreshToken);
return { jwt, user };
}
async validateUser(input: SignInInput) {
const { username, password } = input;
const user = await this.userService.getOne({ where: { username } });
if (!user) {
return null;
}
const isValid: boolean = await bcrypt.compare(password, user.password);
if (!isValid) {
return null;
}
return user;
}
}