-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathauth.service.ts
More file actions
121 lines (99 loc) · 3.85 KB
/
Copy pathauth.service.ts
File metadata and controls
121 lines (99 loc) · 3.85 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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
import { globalConfig } from '@gh/config';
import { User as PrismaUser } from '@gh/prisma';
import { AuthProfile } from '@gh/shared/models';
import { MICROSERVICE_NAME_USERS } from '@gh/shared/utils';
import { Inject, Injectable, UnauthorizedException } from '@nestjs/common';
import { ConfigType } from '@nestjs/config';
import { JwtService } from '@nestjs/jwt';
import { ClientProxy } from '@nestjs/microservices';
import axios from 'axios';
import bcrypt from 'bcrypt';
import { firstValueFrom } from 'rxjs';
@Injectable()
export class AuthService {
constructor(
@Inject(globalConfig.KEY) private readonly config: ConfigType<typeof globalConfig>,
@Inject(MICROSERVICE_NAME_USERS) private readonly usersMicroservice: ClientProxy,
private readonly jwtService: JwtService,
) {}
async validateUser(email: string, password: string) {
const user = await firstValueFrom(this.usersMicroservice.send<PrismaUser>('get_user_by_email', email));
if (await bcrypt.compare(password, user?.password)) {
const { password, ...result } = user;
return result as Partial<PrismaUser>;
}
return null;
}
async validateGoogleUser(email: string) {
const user = await firstValueFrom(this.usersMicroservice.send<PrismaUser>('get_user_by_email', email));
if (user) {
const { password, ...result } = user;
return result as Partial<PrismaUser>;
}
return null;
}
async login(user: PrismaUser) {
const payload = { email: user.email, sub: user.id };
console.log('*** AuthService / login, user =', user, 'payload =', payload);
return {
accessToken: await this.jwtService.signAsync(payload, { secret: this.config.jwt.accessToken.secret, expiresIn: this.config.jwt.accessToken.expiry }),
refreshToken: await this.jwtService.signAsync(payload, { secret: this.config.jwt.refreshToken.secret, expiresIn: this.config.jwt.refreshToken.expiry }),
} as AuthProfile;
}
async refresh(refreshToken: string) {
try {
const decodedToken = this.jwtService.decode(refreshToken);
console.log('*** AuthService / refresh, decodedToken =', decodedToken);
await this.jwtService.verifyAsync(refreshToken, { secret: this.config.jwt.refreshToken.secret });
const { email, sub } = decodedToken;
const payload = { email, sub };
return {
accessToken: await this.jwtService.signAsync(payload, { secret: this.config.jwt.accessToken.secret, expiresIn: this.config.jwt.accessToken.expiry }),
refreshToken: await this.jwtService.signAsync(payload, { secret: this.config.jwt.refreshToken.secret, expiresIn: this.config.jwt.refreshToken.expiry }),
} as AuthProfile;
} catch {
console.log('*** AuthService / refresh, invalid token');
throw new UnauthorizedException();
}
}
async getNewAccessToken(refreshToken: string) {
try {
const response = await axios.post('https://accounts.google.com/o/oauth2/token', {
client_id: this.config.google.clientId,
client_secret: this.config.google.clientSecret,
refresh_token: refreshToken,
grant_type: 'refresh_token',
});
return response.data.access_token as string;
} catch {
throw new Error('Failed to refresh the access token.');
}
}
async getProfile(token: string) {
try {
return axios.get(`https://www.googleapis.com/oauth2/v1/userinfo?alt=json&access_token=${token}`);
} catch (error) {
console.error('Failed to revoke the token:', error);
return null;
}
}
async isTokenExpired(token: string) {
try {
const response = await axios.get(`https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=${token}`);
const expiresIn = response.data.expires_in;
if (!expiresIn || expiresIn <= 0) {
return true;
}
return false;
} catch {
return true;
}
}
async revokeGoogleToken(token: string) {
try {
await axios.get(`https://accounts.google.com/o/oauth2/revoke?token=${token}`);
} catch (error) {
console.error('Failed to revoke the token:', error);
}
}
}