Skip to content

Commit

Permalink
Merge pull request #27 from DevKor-github/refactoring/노정훈
Browse files Browse the repository at this point in the history
Refactoring/노정훈
  • Loading branch information
overthestream authored Jan 27, 2024
2 parents fea4cd9 + ec5c66a commit 12f9f01
Show file tree
Hide file tree
Showing 12 changed files with 385 additions and 332 deletions.
393 changes: 128 additions & 265 deletions src/auth/auth.controller.ts

Large diffs are not rendered by default.

9 changes: 6 additions & 3 deletions src/auth/auth.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,16 @@ import {
AuthPhoneNumberEntity,
UserImageEntity,
} from 'src/entities';
import {
JwtSignupStrategy,
JwtAccessStrategy,
JwtRefreshStrategy,
} from './passport';

import { AuthController } from './auth.controller';
import { AuthService } from './auth.service';
import { PassportModule } from '@nestjs/passport';
import { JwtModule } from '@nestjs/jwt';
import { JwtSignupStrategy } from './passport/jwt-signup.strategy';
import { JwtAccessStrategy } from './passport/jwt-access.strategy';
import { JwtRefreshStrategy } from './passport/jwt-refresh.strategy';
import { MailerModule } from '@nestjs-modules/mailer';
import { UserModule } from 'src/user/user.module';
import { PointModule } from 'src/point/point.module';
Expand Down
56 changes: 32 additions & 24 deletions src/auth/auth.service.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
import {
Injectable,
Logger,
BadRequestException,
ConflictException,
NotAcceptableException,
Expand All @@ -10,11 +9,15 @@ import {
NotFoundException,
} from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { AuthPhoneNumberEntity, AuthMailEntity } from 'src/entities';
import { Repository } from 'typeorm';
import axios from 'axios';
import axios, { AxiosResponse } from 'axios';
import { MailerService } from '@nestjs-modules/mailer';
import { JwtService } from '@nestjs/jwt';
import {
AuthPhoneNumberEntity,
AuthMailEntity,
UserEntity,
} from 'src/entities';
import { UserService } from 'src/user/user.service';
import { JwtPayload, SignupPayload } from 'src/interfaces/auth';
import { UnivMailMap } from 'src/common/const';
Expand All @@ -36,55 +39,53 @@ export class AuthService {
private readonly pointService: PointService,
) {}

private readonly logger = new Logger(AuthService.name);

async getRefreshToken({ id }) {
async getRefreshToken(id: number): Promise<string> {
const payload: JwtPayload = {
id: id,
id,
signedAt: new Date(
new Date().getTime() + 9 * 60 * 60 * 1000,
).toISOString(),
};

const refreshJwt = await this.jwtService.sign(payload, {
const refreshJwt = this.jwtService.sign(payload, {
secret: process.env.REFRESH_TOKEN_SECRET_KEY,
});
this.userService.updateUser(id, 'token', refreshJwt);
await this.userService.updateUser(id, 'token', refreshJwt);

return refreshJwt;
}

async getAccessToken({ id }) {
getAccessToken(id: number): string {
const payload: JwtPayload = {
id: id,
id,
signedAt: new Date(
new Date().getTime() + 9 * 60 * 60 * 1000,
).toISOString(),
};

const accessJwt = await this.jwtService.sign(payload, {
const accessJwt = this.jwtService.sign(payload, {
secret: process.env.ACCESS_TOKEN_SECRET_KEY,
expiresIn: '1h',
});

return accessJwt;
}

async getSignupToken(signupPayload: SignupPayload) {
getSignupToken(signupPayload: SignupPayload): string {
const payload: SignupPayload = {
id: signupPayload.id,
infoId: signupPayload.infoId,
page: signupPayload.page + 1,
};

const signupJwt = await this.jwtService.sign(payload, {
const signupJwt = this.jwtService.sign(payload, {
secret: process.env.JWT_SECRET_KEY,
});

return signupJwt;
}

async validateUser(id: number) {
async validateUser(id: number): Promise<UserEntity> {
const user = await this.userService.findUserByVal('id', id);

if (!user || id == undefined) {
Expand All @@ -93,7 +94,10 @@ export class AuthService {
return user;
}

async validatePhoneNumber(phoneNumber: string, userId: number) {
async validatePhoneNumber(
phoneNumber: string,
userId: number,
): Promise<void> {
const phone = await this.authPhoneNumberRepository.findOne({
where: { user: { id: userId }, isValid: false },
order: { createdAt: 'DESC' },
Expand Down Expand Up @@ -157,7 +161,7 @@ export class AuthService {
hmac.update('\n');
hmac.update(`${accessKey}`);
const hash = hmac.digest('base64');
let response;
let response: AxiosResponse<any, any>;
try {
response = await axios.post(API_URL, body, {
headers: {
Expand All @@ -177,7 +181,11 @@ export class AuthService {
);
}

async checkCode(userId: number, code: string, phoneNumber: string) {
async checkCode(
userId: number,
code: string,
phoneNumber: string,
): Promise<boolean> {
const phone = await this.authPhoneNumberRepository.findOne({
where: { user: { id: userId }, code },
relations: ['user'],
Expand All @@ -200,7 +208,7 @@ export class AuthService {
return true;
}

async sendVerificationCode(userId: number, to: string) {
async sendVerificationCode(userId: number, to: string): Promise<void> {
const existingUser = await this.userService.findUserByVal('email', to);
if (existingUser) throw new ConflictException('이미 가입된 이메일입니다.');
const mail = await this.authMailRepository.findOne({
Expand Down Expand Up @@ -241,12 +249,12 @@ export class AuthService {
await this.authMailRepository.save(entity);
}

async checkComplete(id: number) {
async checkComplete(id: number): Promise<boolean> {
const user = await this.userService.findUserByVal('id', id);
return user.phoneNumber && user.email != null;
}

async checkMail(code: string, email: string) {
async checkMail(code: string, email: string): Promise<void> {
const mail = await this.authMailRepository.findOne({
where: {
code: code,
Expand All @@ -269,7 +277,7 @@ export class AuthService {
await this.authMailRepository.delete(mail);
}

async alreadySigned(phoneNumber: string) {
async alreadySigned(phoneNumber: string): Promise<boolean> {
const user = await this.userService.findUserByPhone(phoneNumber);
if (!user) throw new NotFoundException('가입되지 않은 전화번호입니다.');

Expand Down Expand Up @@ -373,8 +381,8 @@ export class AuthService {

await this.authPhoneNumberRepository.delete(phone);
const id = phone.user.id;
const refreshJwt = await this.getRefreshToken({ id });
const accessJwt = await this.getAccessToken({ id });
const refreshJwt = await this.getRefreshToken(id);
const accessJwt = await this.getAccessToken(id);
await this.userService.createSocketUser(id);

return { refreshToken: refreshJwt, accessToken: accessJwt, id };
Expand Down
5 changes: 5 additions & 0 deletions src/auth/guard/acces.guard.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { Injectable } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';

@Injectable()
export class AccessGuard extends AuthGuard('access') {}
5 changes: 5 additions & 0 deletions src/auth/guard/refresh.guard.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { Injectable } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';

@Injectable()
export class RefreshGuard extends AuthGuard('refresh') {}
27 changes: 2 additions & 25 deletions src/auth/guard/signup.guard.ts
Original file line number Diff line number Diff line change
@@ -1,28 +1,5 @@
import { Injectable, ExecutionContext } from '@nestjs/common';
import { AuthService } from '../auth.service';
import { UserService } from 'src/user/user.service';
import { Injectable } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
import { Reflector } from '@nestjs/core';
import { lastValueFrom, Observable } from 'rxjs';

@Injectable()
export class SignupGuard extends AuthGuard('signup') {
constructor(
private readonly authService: AuthService,
private readonly userService: UserService,
private readonly reflector: Reflector,
) {
super(reflector);
}

async canActivate(context: ExecutionContext): Promise<boolean> {
const result = super.canActivate(context);
if (typeof result === 'boolean' || result instanceof Promise) {
return result;
} else if (result instanceof Observable) {
return await lastValueFrom(result);
} else {
throw new Error('Unexpected canActivate return value');
}
}
}
export class SignupGuard extends AuthGuard('signup') {}
3 changes: 3 additions & 0 deletions src/auth/passport/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export * from './jwt-access.strategy';
export * from './jwt-refresh.strategy';
export * from './jwt-signup.strategy';
13 changes: 3 additions & 10 deletions src/auth/passport/jwt-access.strategy.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,18 @@
import { Injectable, HttpException } from '@nestjs/common';
import { Injectable } from '@nestjs/common';
import { PassportStrategy } from '@nestjs/passport';
import { Strategy, ExtractJwt } from 'passport-jwt';
import { JwtPayload } from 'src/interfaces/auth';
import { UserService } from 'src/user/user.service';

@Injectable()
export class JwtAccessStrategy extends PassportStrategy(Strategy, 'access') {
constructor(private readonly userService: UserService) {
constructor() {
super({
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
secretOrKey: process.env.ACCESS_TOKEN_SECRET_KEY,
});
}

async validate(payload: JwtPayload) {
const user = await this.userService.findUserByVal('id', payload.id);

if (!user || user.id != payload.id) {
throw new HttpException('Invalid access token', 401);
}

return user;
return payload;
}
}
3 changes: 1 addition & 2 deletions src/auth/passport/jwt-signup.strategy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,10 @@ import { Injectable, UnauthorizedException } from '@nestjs/common';
import { PassportStrategy } from '@nestjs/passport';
import { Strategy, ExtractJwt } from 'passport-jwt';
import { SignupPayload } from 'src/interfaces/auth';
import { UserService } from 'src/user/user.service';

@Injectable()
export class JwtSignupStrategy extends PassportStrategy(Strategy, 'signup') {
constructor(private readonly userService: UserService) {
constructor() {
super({
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
secretOrKey: process.env.JWT_SECRET_KEY,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { createParamDecorator, ExecutionContext } from '@nestjs/common';
import { JwtPayload } from 'src/interfaces/auth';

export const User = createParamDecorator(
(data: unknown, ctx: ExecutionContext) => {
(_: unknown, ctx: ExecutionContext) => {
const request = ctx.switchToHttp().getRequest();

console.log(data);
return request.user;
return request.user as JwtPayload;
},
);
10 changes: 10 additions & 0 deletions src/decorators/signupUser.decorator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { createParamDecorator, ExecutionContext } from '@nestjs/common';
import { SignupPayload } from 'src/interfaces/auth';

export const SignupUser = createParamDecorator(
(_: never, ctx: ExecutionContext) => {
const request = ctx.switchToHttp().getRequest();

return request.user as SignupPayload;
},
);
Loading

0 comments on commit 12f9f01

Please sign in to comment.