diff --git a/src/auth/services/auth.service.ts b/src/auth/services/auth.service.ts index 1e3e441..ea21e2b 100644 --- a/src/auth/services/auth.service.ts +++ b/src/auth/services/auth.service.ts @@ -13,7 +13,7 @@ export class AuthService { private readonly userRepository: UserRepository, private readonly userImageRepository: UserImageRepository, private readonly tokenService: TokenService, - ) {} + ) {} async naverLogin(authorizeCode: string) { try { @@ -32,11 +32,13 @@ export class AuthService { redirect_uri: process.env.NAVER_CALLBACK_URL, }; - const naverToken = (await axios.post(naverTokenUrl, naverTokenBody, naverTokenHeader)).data; + const naverToken = ( + await axios.post(naverTokenUrl, naverTokenBody, naverTokenHeader) + ).data; const naverAccessToken = naverToken.access_token; const naverRefreshToken = naverToken.refresh_token; - + const naverUserInfoUrl = 'https://openapi.naver.com/v1/nid/me'; const naverUserInfoHeader = { headers: { @@ -44,7 +46,9 @@ export class AuthService { }, }; - const naverUserInfo = (await axios.get(naverUserInfoUrl, naverUserInfoHeader)).data; + const naverUserInfo = ( + await axios.get(naverUserInfoUrl, naverUserInfoHeader) + ).data; const nickname = naverUserInfo.response.nickname; const email = naverUserInfo.response.email; const profileImage = naverUserInfo.response.profile_image; @@ -58,25 +62,33 @@ export class AuthService { }; const checkUser = await this.userRepository.findUser(email, provider); - if (checkUser) { // 이미 존재하는 사용자인 경우 + if (checkUser) { + // 이미 존재하는 사용자인 경우 const userId = checkUser.id; await this.userRepository.updateUserName(userId, nickname); // 이름 업데이트 - const userImage = (await this.userImageRepository.checkUserImage(userId)).imageUrl; // DB 이미지 + const userImage = ( + await this.userImageRepository.checkUserImage(userId) + ).imageUrl; // DB 이미지 const imageUrlParts = userImage.split('/'); const dbImageProvider = imageUrlParts[imageUrlParts.length - 2]; // 이미지 제공자 이름 - if (dbImageProvider != 'ma6-main.s3.ap-northeast-2.amazonaws.com') { // S3에 업로드된 이미지가 아닌 경우 + if (dbImageProvider != 'ma6-main.s3.ap-northeast-2.amazonaws.com') { + // S3에 업로드된 이미지가 아닌 경우 await this.userImageRepository.updateUserImage(userId, profileImage); // DB에 이미지 URL 업데이트 } return { userId, naverAccessToken, naverRefreshToken }; - } else { // 존재하지 않는 사용자인 경우 + } else { + // 존재하지 않는 사용자인 경우 const newUser = await this.userRepository.createUser(userInfo); const userId = newUser.id; if (!profileImage) { - await this.userImageRepository.uploadUserImage(userId, process.env.DEFAULT_USER_IMAGE); + await this.userImageRepository.uploadUserImage( + userId, + process.env.DEFAULT_USER_IMAGE, + ); } else { await this.userImageRepository.uploadUserImage(userId, profileImage); } @@ -84,7 +96,10 @@ export class AuthService { } } catch (error) { if (error.response.status == 401) { - throw new HttpException('유효하지 않은 인가코드입니다.', HttpStatus.UNAUTHORIZED); + throw new HttpException( + '유효하지 않은 인가코드입니다.', + HttpStatus.UNAUTHORIZED, + ); } } } @@ -104,7 +119,9 @@ export class AuthService { code: authorizeCode, }; - const kakaoToken = (await axios.post(kakaoTokenUrl, kakaoTokenBody, kakaoTokenHeader)).data; + const kakaoToken = ( + await axios.post(kakaoTokenUrl, kakaoTokenBody, kakaoTokenHeader) + ).data; const kakaoAccessToken = kakaoToken.access_token; const kakaoRefreshToken = kakaoToken.refresh_token; @@ -116,7 +133,9 @@ export class AuthService { }, }; - const kakaoUserInfo = (await axios.get(kakaoUserInfoUrl, kakaoUserInfoHeader)).data; + const kakaoUserInfo = ( + await axios.get(kakaoUserInfoUrl, kakaoUserInfoHeader) + ).data; const nickname = kakaoUserInfo.properties.nickname; const email = kakaoUserInfo.kakao_account.email; const profileImage = kakaoUserInfo.properties.profile_image; @@ -127,28 +146,36 @@ export class AuthService { nickname, email, gender, - } + }; const checkUser = await this.userRepository.findUser(email, provider); - if (checkUser) { // 이미 존재하는 사용자인 경우 + if (checkUser) { + // 이미 존재하는 사용자인 경우 const userId = checkUser.id; await this.userRepository.updateUserName(userId, nickname); // 이름 업데이트 - - const userImage = (await this.userImageRepository.checkUserImage(userId)).imageUrl; // DB 이미지 + + const userImage = ( + await this.userImageRepository.checkUserImage(userId) + ).imageUrl; // DB 이미지 const imageUrlParts = userImage.split('/'); const dbImageProvider = imageUrlParts[imageUrlParts.length - 2]; // 이미지 제공자 이름 - if (dbImageProvider != 'ma6-main.s3.ap-northeast-2.amazonaws.com') { // S3에 업로드된 이미지가 아닌 경우 + if (dbImageProvider != 'ma6-main.s3.ap-northeast-2.amazonaws.com') { + // S3에 업로드된 이미지가 아닌 경우 await this.userImageRepository.updateUserImage(userId, profileImage); // DB에 이미지 URL 업데이트 } return { userId, kakaoAccessToken, kakaoRefreshToken }; - } else { // 존재하지 않는 사용자인 경우 + } else { + // 존재하지 않는 사용자인 경우 const newUser = await this.userRepository.createUser(userInfo); const userId = newUser.id; if (!profileImage) { - await this.userImageRepository.uploadUserImage(userId, process.env.DEFAULT_USER_IMAGE); + await this.userImageRepository.uploadUserImage( + userId, + process.env.DEFAULT_USER_IMAGE, + ); } else { await this.userImageRepository.uploadUserImage(userId, profileImage); } @@ -156,16 +183,27 @@ export class AuthService { } } catch (error) { if (error.response.status == 400) { - throw new HttpException('유효하지 않은 인가코드입니다.', HttpStatus.UNAUTHORIZED); + throw new HttpException( + '유효하지 않은 인가코드입니다.', + HttpStatus.UNAUTHORIZED, + ); + } else { + console.log(error); + throw new HttpException( + '카카오 로그인 중 오류가 발생했습니다.', + HttpStatus.INTERNAL_SERVER_ERROR, + ); } } } async kakaoLogout(accessToken: string, refreshToken: string) { try { - const checkValidKakaoToken = await this.tokenService.checkValidKakaoToken(accessToken); + const checkValidKakaoToken = + await this.tokenService.checkValidKakaoToken(accessToken); if (checkValidKakaoToken === 401) { - const newKakaoToken = await this.tokenService.getNewKakaoToken(refreshToken); + const newKakaoToken = + await this.tokenService.getNewKakaoToken(refreshToken); accessToken = newKakaoToken.access_token; } @@ -177,18 +215,23 @@ export class AuthService { }; axios.post(kakaoLogoutUrl, {}, kakaoLogoutHeader); - return { message: "카카오 로그아웃이 완료되었습니다." }; + return { message: '카카오 로그아웃이 완료되었습니다.' }; } catch (error) { console.log(error); - throw new HttpException('카카오 로그아웃 중 오류가 발생했습니다.', HttpStatus.INTERNAL_SERVER_ERROR) + throw new HttpException( + '카카오 로그아웃 중 오류가 발생했습니다.', + HttpStatus.INTERNAL_SERVER_ERROR, + ); } } async kakaoUnlink(accessToken: string, refreshToken: string) { try { - const checkValidKakaoToken = await this.tokenService.checkValidKakaoToken(accessToken); + const checkValidKakaoToken = + await this.tokenService.checkValidKakaoToken(accessToken); if (checkValidKakaoToken === 401) { - const newKakaoToken = await this.tokenService.getNewKakaoToken(refreshToken); + const newKakaoToken = + await this.tokenService.getNewKakaoToken(refreshToken); accessToken = newKakaoToken.access_token; } @@ -200,18 +243,23 @@ export class AuthService { }; axios.post(kakaoUnlinkUrl, {}, kakaoUnlinkHeader); - return { message: "카카오 연결 끊기가 완료되었습니다." }; + return { message: '카카오 연결 끊기가 완료되었습니다.' }; } catch (error) { console.log(error); - throw new HttpException('카카오 연결 끊기 중 오류가 발생했습니다.', HttpStatus.INTERNAL_SERVER_ERROR) + throw new HttpException( + '카카오 연결 끊기 중 오류가 발생했습니다.', + HttpStatus.INTERNAL_SERVER_ERROR, + ); } } async naverUnlink(accessToken: string, refreshToken: string) { try { - const checkValidNaverToken = await this.tokenService.checkValidNaverToken(accessToken); + const checkValidNaverToken = + await this.tokenService.checkValidNaverToken(accessToken); if (checkValidNaverToken === 401) { - const newNaverToken = await this.tokenService.getNewNaverToken(refreshToken); + const newNaverToken = + await this.tokenService.getNewNaverToken(refreshToken); accessToken = newNaverToken.access_token; } @@ -229,18 +277,24 @@ export class AuthService { }; axios.post(naverUnlinkUrl, naverUnlinkBody, naverUnlinkHeader); - return { message: "네이버 연동 해제가 완료되었습니다." }; + return { message: '네이버 연동 해제가 완료되었습니다.' }; } catch (error) { console.log(error); - throw new HttpException('네이버 연결 끊기 중 오류가 발생했습니다.', HttpStatus.INTERNAL_SERVER_ERROR) + throw new HttpException( + '네이버 연결 끊기 중 오류가 발생했습니다.', + HttpStatus.INTERNAL_SERVER_ERROR, + ); } } async accountDelete(userId: number) { const deleteUser = await this.userRepository.deleteUser(userId); if (!deleteUser) { - throw new HttpException('사용자를 찾을 수 없습니다.', HttpStatus.NOT_FOUND); + throw new HttpException( + '사용자를 찾을 수 없습니다.', + HttpStatus.NOT_FOUND, + ); } - return { message: "사용자 계정 삭제가 완료되었습니다." }; + return { message: '사용자 계정 삭제가 완료되었습니다.' }; } } diff --git a/src/common/decorators/get-userId.decorator.ts b/src/common/decorators/get-userId.decorator.ts index c8aec4a..3160022 100644 --- a/src/common/decorators/get-userId.decorator.ts +++ b/src/common/decorators/get-userId.decorator.ts @@ -3,7 +3,9 @@ import { ExecutionContext, createParamDecorator } from '@nestjs/common'; export const GetUserId = createParamDecorator( (data, ctx: ExecutionContext): number => { const req = ctx.switchToHttp().getRequest(); - + if (!req.user) { + return null; + } return req.user.userId; }, -); \ No newline at end of file +); diff --git a/src/config/guards/jwt-access-token.guard.ts b/src/config/guards/jwt-access-token.guard.ts index 9c7451d..d7b507f 100644 --- a/src/config/guards/jwt-access-token.guard.ts +++ b/src/config/guards/jwt-access-token.guard.ts @@ -10,7 +10,7 @@ export class JwtAccessTokenGuard { const accessToken = request.headers['access_token']; if (!accessToken) { - return false; + return true; } const userId = await this.tokenService.decodeToken(accessToken); diff --git a/src/users/services/user.service.ts b/src/users/services/user.service.ts index 3b92bb7..ddcd6c7 100644 --- a/src/users/services/user.service.ts +++ b/src/users/services/user.service.ts @@ -1,4 +1,4 @@ -import { Injectable } from '@nestjs/common'; +import { HttpException, HttpStatus, Injectable } from '@nestjs/common'; import { UserRepository } from '../repositories/user.repository'; import { UserImageRepository } from '../repositories/user-image.repository'; @@ -10,6 +10,12 @@ export class UserService { ) {} async getMyInfo(userId: number) { + if (!userId) { + throw new HttpException( + '토큰이 제공되지 않았습니다.', + HttpStatus.LENGTH_REQUIRED, + ); + } const { name, email, gender, admin, provider } = await this.userRepository.getUserInfo(userId); const userImage = (await this.userImageRepository.checkUserImage(userId))