Skip to content

Commit ef0e1ae

Browse files
authored
Merge pull request #84 from CS3219-AY2425S1/ms4-evan/matching-logic
Enhance matching validation logic
2 parents 91d49cb + 30a7636 commit ef0e1ae

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

67 files changed

+894
-264
lines changed

backend/auth-service/.env.example

Lines changed: 0 additions & 22 deletions
This file was deleted.

backend/auth-service/package-lock.json

Lines changed: 13 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

backend/auth-service/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
"bcryptjs": "^2.4.3",
3232
"class-transformer": "^0.5.1",
3333
"class-validator": "^0.14.1",
34+
"dotenv": "^16.4.5",
3435
"google-auth-library": "^9.14.1",
3536
"nodemailer": "^6.9.15",
3637
"passport": "^0.7.0",

backend/auth-service/src/app.module.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,22 @@ import {
1111
GoogleStrategy,
1212
GithubStrategy,
1313
} from './strategies';
14+
import { config } from './configs';
1415

1516
@Module({
1617
imports: [
17-
PassportModule.register({ defaultStrategy: 'jwt' }),
18+
PassportModule.register({
19+
defaultStrategy: config.strategies.accessTokenStrategy,
20+
}),
1821
HttpModule,
1922
JwtModule.register({}),
2023
ClientsModule.register([
2124
{
2225
name: 'USER_SERVICE',
23-
transport: Transport.TCP,
26+
transport: config.userService.transport,
2427
options: {
25-
host: 'user-service',
26-
port: 3001,
28+
host: config.userService.host,
29+
port: config.userService.port,
2730
},
2831
},
2932
]),

backend/auth-service/src/app.service.ts

Lines changed: 24 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import axios, { AxiosResponse } from 'axios';
1717
import { Token, TokenPayload } from './interfaces';
1818
import { AccountProvider } from './constants/account-provider.enum';
1919
import * as nodemailer from 'nodemailer';
20+
import { config } from 'src/configs';
2021

2122
const SALT_ROUNDS = 10;
2223

@@ -30,9 +31,9 @@ export class AppService {
3031
@Inject('USER_SERVICE') private readonly userClient: ClientProxy,
3132
) {
3233
this.oauthClient = new OAuth2Client({
33-
clientId: process.env.GOOGLE_CLIENT_ID,
34-
clientSecret: process.env.GOOGLE_CLIENT_SECRET,
35-
redirectUri: process.env.GOOGLE_CALLBACK_URL,
34+
clientId: config.auth.google.clientId,
35+
clientSecret: config.auth.google.clientSecret,
36+
redirectUri: config.auth.google.callbackUrl,
3637
});
3738
}
3839

@@ -173,8 +174,8 @@ export class AppService {
173174
const resetToken = this.jwtService.sign(
174175
{ userId: user._id.toString(), email: dto.email, type: 'reset-password' },
175176
{
176-
secret: process.env.JWT_SECRET,
177-
expiresIn: '1hr',
177+
secret: config.auth.local.jwtSecret,
178+
expiresIn: config.auth.local.jwtTokenExpiration,
178179
},
179180
);
180181

@@ -206,7 +207,7 @@ export class AppService {
206207
public async validatePasswordResetToken(token: string): Promise<any> {
207208
try {
208209
const decoded = this.jwtService.verify(token, {
209-
secret: process.env.JWT_SECRET,
210+
secret: config.auth.local.jwtSecret,
210211
});
211212
const { userId, email, type } = decoded;
212213
if (type !== 'reset-password') {
@@ -225,16 +226,16 @@ export class AppService {
225226
}
226227

227228
private async sendResetEmail(email: string, token: string) {
228-
const resetUrl = `${process.env.FRONTEND_URL}/reset-password?token=${token}`; // To change next time
229+
const resetUrl = `${config.frontendUrl}/reset-password?token=${token}`; // To change next time
229230

230231
const transporter = nodemailer.createTransport({
231232
service: 'gmail',
232233
host: 'smtp.gmail.com',
233234
port: 465,
234235
secure: true,
235236
auth: {
236-
user: process.env.NODEMAILER_GMAIL_USER,
237-
pass: process.env.NODEMAILER_GMAIL_PASSWORD,
237+
user: config.mailer.user,
238+
pass: config.mailer.password,
238239
},
239240
});
240241

@@ -255,7 +256,7 @@ export class AppService {
255256
public async validateAccessToken(accessToken: string): Promise<any> {
256257
try {
257258
const decoded = this.jwtService.verify(accessToken, {
258-
secret: process.env.JWT_SECRET,
259+
secret: config.auth.local.jwtSecret,
259260
});
260261
return decoded;
261262
} catch (error) {
@@ -266,7 +267,7 @@ export class AppService {
266267
public async validateRefreshToken(refreshToken: string): Promise<any> {
267268
try {
268269
const decoded = this.jwtService.verify(refreshToken, {
269-
secret: process.env.JWT_REFRESH_SECRET,
270+
secret: config.auth.local.jwtRefreshSecret,
270271
});
271272
return decoded;
272273
} catch (error) {
@@ -300,8 +301,8 @@ export class AppService {
300301
...rest,
301302
},
302303
{
303-
secret: process.env.JWT_SECRET,
304-
expiresIn: '1h', // 1 hour
304+
secret: config.auth.local.jwtSecret,
305+
expiresIn: config.auth.local.jwtTokenExpiration,
305306
},
306307
),
307308
this.jwtService.signAsync(
@@ -310,8 +311,8 @@ export class AppService {
310311
...rest,
311312
},
312313
{
313-
secret: process.env.JWT_REFRESH_SECRET,
314-
expiresIn: '7d', // 1 week
314+
secret: config.auth.local.jwtRefreshSecret,
315+
expiresIn: config.auth.local.jwtRefreshTokenExpiration,
315316
},
316317
),
317318
]);
@@ -323,8 +324,8 @@ export class AppService {
323324
}
324325

325326
getGoogleOAuthUrl(): string {
326-
const clientId = process.env.GOOGLE_CLIENT_ID;
327-
const redirectUri = process.env.GOOGLE_CALLBACK_URL;
327+
const clientId = config.auth.google.clientId;
328+
const redirectUri = config.auth.google.callbackUrl;
328329
const scope = encodeURIComponent('email profile');
329330
const responseType = 'code';
330331
const state = 'secureRandomState';
@@ -404,7 +405,7 @@ export class AppService {
404405

405406
const ticket = await this.oauthClient.verifyIdToken({
406407
idToken: tokens.id_token,
407-
audience: process.env.GOOGLE_CLIENT_ID,
408+
audience: config.auth.google.clientId,
408409
});
409410

410411
const payload = ticket.getPayload();
@@ -428,8 +429,8 @@ export class AppService {
428429
}
429430

430431
getGithubOAuthUrl(): string {
431-
const clientId = process.env.GITHUB_CLIENT_ID;
432-
const redirectUri = process.env.GITHUB_CALLBACK_URL;
432+
const clientId = config.auth.github.clientId;
433+
const redirectUri = config.auth.github.callbackUrl;
433434
const scope = 'user:email';
434435

435436
const githubLoginUrl = `https://github.com/login/oauth/authorize?client_id=${clientId}&redirect_uri=${encodeURIComponent(
@@ -486,10 +487,10 @@ export class AppService {
486487
private async exchangeGithubCodeForTokens(code: string) {
487488
try {
488489
const params = {
489-
client_id: process.env.GITHUB_CLIENT_ID,
490-
client_secret: process.env.GITHUB_CLIENT_SECRET,
490+
client_id: config.auth.github.clientId,
491+
client_secret: config.auth.github.clientSecret,
491492
code: code,
492-
redirect_uri: process.env.GITHUB_CALLBACK_URL,
493+
redirect_uri: config.auth.github.callbackUrl,
493494
};
494495
const headers = {
495496
Accept: 'application/json',
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import { Transport } from '@nestjs/microservices';
2+
import * as dotenv from 'dotenv';
3+
4+
dotenv.config();
5+
6+
function getEnvVar(name: string): string {
7+
const value = process.env[name];
8+
if (!value) {
9+
throw new Error(`Environment variable ${name} is not defined`);
10+
}
11+
return value;
12+
}
13+
14+
export const config = {
15+
userService: {
16+
port: parseInt(getEnvVar('USER_SERVICE_PORT')),
17+
host: getEnvVar('USER_SERVICE_HOST'),
18+
transport: Transport[getEnvVar('USER_SERVICE_TRANSPORT')] || Transport.TCP,
19+
},
20+
authService: {
21+
port: parseInt(getEnvVar('AUTH_SERVICE_PORT')),
22+
host: getEnvVar('AUTH_SERVICE_HOST'),
23+
transport: Transport[getEnvVar('AUTH_SERVICE_TRANSPORT')] || Transport.TCP,
24+
},
25+
strategies: {
26+
accessTokenStrategy: getEnvVar('ACCESS_TOKEN_STRATEGY'),
27+
refreshTokenStrategy: getEnvVar('REFRESH_TOKEN_STRATEGY'),
28+
googleStrategy: getEnvVar('GOOGLE_STRATEGY'),
29+
githubStrategy: getEnvVar('GITHUB_STRATEGY'),
30+
},
31+
auth: {
32+
local: {
33+
jwtSecret: getEnvVar('JWT_SECRET'),
34+
jwtTokenExpiration: getEnvVar('JWT_TOKEN_EXPIRATION'),
35+
jwtRefreshSecret: getEnvVar('JWT_REFRESH_SECRET'),
36+
jwtRefreshTokenExpiration: getEnvVar('JWT_REFRESH_TOKEN_EXPIRATION'),
37+
},
38+
google: {
39+
clientId: getEnvVar('GOOGLE_CLIENT_ID'),
40+
clientSecret: getEnvVar('GOOGLE_CLIENT_SECRET'),
41+
callbackUrl: getEnvVar('GOOGLE_CALLBACK_URL'),
42+
},
43+
github: {
44+
clientId: getEnvVar('GITHUB_CLIENT_ID'),
45+
clientSecret: getEnvVar('GITHUB_CLIENT_SECRET'),
46+
callbackUrl: getEnvVar('GITHUB_CALLBACK_URL'),
47+
},
48+
},
49+
mailer: {
50+
user: getEnvVar('NODEMAILER_GMAIL_USER'),
51+
password: getEnvVar('NODEMAILER_GMAIL_PASSWORD'),
52+
},
53+
frontendUrl: getEnvVar('FRONTEND_URL'),
54+
};
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { config } from './env.config';

backend/auth-service/src/main.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,24 @@ import { NestFactory } from '@nestjs/core';
22
import { AppModule } from './app.module';
33
import { MicroserviceOptions, Transport } from '@nestjs/microservices';
44
import { ValidationPipe } from '@nestjs/common';
5+
import { config } from 'src/configs';
6+
import * as dotenv from 'dotenv';
7+
8+
dotenv.config();
59

610
async function bootstrap() {
711
const app = await NestFactory.createMicroservice<MicroserviceOptions>(
812
AppModule,
913
{
10-
transport: Transport.TCP,
14+
transport: config.authService.transport,
1115
options: {
12-
host: '0.0.0.0',
13-
port: 3003,
16+
host: config.authService.host,
17+
port: config.authService.port,
1418
},
1519
},
1620
);
1721
app.useGlobalPipes(new ValidationPipe());
1822
await app.listen();
19-
console.log('Auth Service is listening on port 3003');
23+
console.log('Auth Service is listening on port', config.authService.port);
2024
}
2125
bootstrap();

backend/auth-service/src/strategies/access-token.strategy.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,18 @@
11
import { Injectable } from '@nestjs/common';
22
import { PassportStrategy } from '@nestjs/passport';
33
import { Strategy, ExtractJwt } from 'passport-jwt';
4+
import { config } from 'src/configs';
45

56
@Injectable()
6-
export class AccessTokenStrategy extends PassportStrategy(Strategy, 'jwt') {
7+
export class AccessTokenStrategy extends PassportStrategy(
8+
Strategy,
9+
config.strategies.accessTokenStrategy,
10+
) {
711
constructor() {
812
super({
913
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
1014
ignoreExpiration: false,
11-
secretOrKey: process.env.JWT_SECRET,
15+
secretOrKey: config.auth.local.jwtSecret,
1216
});
1317
}
1418

backend/auth-service/src/strategies/github.strategy.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,18 @@
11
import { PassportStrategy } from '@nestjs/passport';
22
import { Strategy, VerifyCallback } from 'passport-google-oauth20';
33
import { Injectable } from '@nestjs/common';
4+
import { config } from 'src/configs';
45

56
@Injectable()
6-
export class GithubStrategy extends PassportStrategy(Strategy, 'github') {
7+
export class GithubStrategy extends PassportStrategy(
8+
Strategy,
9+
config.strategies.githubStrategy,
10+
) {
711
constructor() {
812
super({
9-
clientID: process.env.GITHUB_CLIENT_ID,
10-
clientSecret: process.env.GITHUB_CLIENT_SECRET,
11-
callbackURL: process.env.GITHUB_CALLBACK_URL,
13+
clientID: config.auth.github.clientId,
14+
clientSecret: config.auth.github.clientSecret,
15+
callbackURL: config.auth.github.callbackUrl,
1216
scope: ['user:email'],
1317
});
1418
}

0 commit comments

Comments
 (0)