From 0c1591df11c4a862a892058412b6ecb9b9e24dfc Mon Sep 17 00:00:00 2001 From: jiyun Date: Wed, 24 Apr 2024 23:19:46 +0900 Subject: [PATCH 1/2] =?UTF-8?q?fix:=20s3=20image=20=EC=97=85=EB=A1=9C?= =?UTF-8?q?=EB=93=9C=20=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/auth/auth.controller.ts | 2 +- src/auth/auth.service.ts | 30 ++++-- src/auth/dto/signup-request.dto.ts | 3 +- .../dto/channel-Invitation-list-return.dto.ts | 30 +++--- .../dto/channel-user-info-return.dto.ts | 2 +- src/channels/dto/dmchannel-list-return.dto.ts | 10 +- src/common/constants.ts | 7 ++ src/friends/dto/block-user-return.dto.ts | 3 +- src/friends/dto/friend-user-return.dto.ts | 2 +- .../dto/emit-event-match-end-param.dto.ts | 2 +- .../emit-event-server-game-ready-param.dto.ts | 2 +- .../dto/my-profile-response.dto.ts | 2 +- .../dto/user-profile-return.dto.ts | 2 +- src/user-repository/entities/user.entity.ts | 4 +- src/user-repository/users.repository.ts | 62 +++++++++++- src/users/dto/rank-user-return.dto.ts | 2 +- src/users/dto/user-profile-response.dto.ts | 2 +- src/users/ranks.service.ts | 10 +- src/users/users.controller.ts | 34 ++----- src/users/users.service.ts | 94 +++++++------------ 20 files changed, 171 insertions(+), 134 deletions(-) diff --git a/src/auth/auth.controller.ts b/src/auth/auth.controller.ts index e561e24..437415c 100644 --- a/src/auth/auth.controller.ts +++ b/src/auth/auth.controller.ts @@ -111,7 +111,7 @@ export class AuthController { const nickname = signupRequestDto.nickname; const avatar = signupRequestDto.avatar; - await this.authService.signup(user.id, nickname, avatar); + return await this.authService.signup(user.id, nickname, avatar); } // TODO: 테스트용 코드. 추후 삭제 diff --git a/src/auth/auth.service.ts b/src/auth/auth.service.ts index 2dbf846..1b8f63e 100644 --- a/src/auth/auth.service.ts +++ b/src/auth/auth.service.ts @@ -34,22 +34,40 @@ export class AuthService { private readonly logger = new Logger(AuthService.name); - async signup(userId: number, nickname: string, avatar: string) { + async signup(userId: number, nickname: string, hasAvatar: boolean) { const user = await this.validateUserExist(userId); await this.validateUserAlreadySignUp(user); await this.validateNickname(nickname); + let ret; + let updateUserDataDto; + if (hasAvatar) { + const { avatar, preSignedUrl } = + await this.usersRepository.getAvatarAndPresignedUrl(nickname); + updateUserDataDto = { + nickname: nickname, + avatar: avatar, + }; + ret = preSignedUrl; + } else { + updateUserDataDto = { + nickname: nickname, + }; + ret = null; + } + const updateRes = await this.usersRepository.update(userId, { - avatar: avatar, - nickname: nickname, - status: UserStatus.ONLINE, + ...updateUserDataDto, }); - if (updateRes.affected !== 1) { - throw DBUpdateFailureException(`user ${userId} update failed`); + throw DBUpdateFailureException( + `유저 ${userId}의 db 업데이트가 실패했습니다`, + ); } + + return ret; } async validateUserExist(userId: number) { diff --git a/src/auth/dto/signup-request.dto.ts b/src/auth/dto/signup-request.dto.ts index 31efe96..a8d04de 100644 --- a/src/auth/dto/signup-request.dto.ts +++ b/src/auth/dto/signup-request.dto.ts @@ -5,8 +5,7 @@ import { ApiProperty } from '@nestjs/swagger'; export class SignupRequestDto { @ApiProperty({ description: '아바타' }) @IsNotEmpty() - @IsString() - avatar: string; + avatar: boolean; @ApiProperty({ description: '닉네임' }) @IsNotEmpty() @IsString() diff --git a/src/channels/dto/channel-Invitation-list-return.dto.ts b/src/channels/dto/channel-Invitation-list-return.dto.ts index d8c78f3..6c3cac2 100644 --- a/src/channels/dto/channel-Invitation-list-return.dto.ts +++ b/src/channels/dto/channel-Invitation-list-return.dto.ts @@ -2,18 +2,18 @@ import { ApiProperty } from '@nestjs/swagger'; import { ChannelUserType } from 'src/common/enum'; export class ChannelInvitationListDto { - @ApiProperty({ description: '채널유저id' }) - channelUserId: number; - @ApiProperty({ description: '유저id' }) - userId : number; - @ApiProperty({ description: '유저닉네임' }) - nickname : string; - @ApiProperty({ description: '유저아바타' }) - avatar : string; - @ApiProperty({ description: '친구여부' }) - isFriend : boolean; - @ApiProperty({ description: '차단여부' }) - isBlocked : boolean; - @ApiProperty({ description: '채널유저타입' }) - channelUserType : ChannelUserType; -} \ No newline at end of file + @ApiProperty({ description: '채널유저id' }) + channelUserId: number; + @ApiProperty({ description: '유저id' }) + userId: number; + @ApiProperty({ description: '유저닉네임' }) + nickname: string; + @ApiProperty({ description: '유저아바타' }) + avatar: string | null; + @ApiProperty({ description: '친구여부' }) + isFriend: boolean; + @ApiProperty({ description: '차단여부' }) + isBlocked: boolean; + @ApiProperty({ description: '채널유저타입' }) + channelUserType: ChannelUserType; +} diff --git a/src/channels/dto/channel-user-info-return.dto.ts b/src/channels/dto/channel-user-info-return.dto.ts index ac7aab4..4921138 100644 --- a/src/channels/dto/channel-user-info-return.dto.ts +++ b/src/channels/dto/channel-user-info-return.dto.ts @@ -4,7 +4,7 @@ export type ChannelUserInfoReturnDto = { channelUserId: number; userId: number; nickname: string; - avatar: string; + avatar: string | null; isFriend: boolean; isBlocked: boolean; channelUserType: ChannelUserType; diff --git a/src/channels/dto/dmchannel-list-return.dto.ts b/src/channels/dto/dmchannel-list-return.dto.ts index 3629eaa..4bf0a42 100644 --- a/src/channels/dto/dmchannel-list-return.dto.ts +++ b/src/channels/dto/dmchannel-list-return.dto.ts @@ -1,6 +1,6 @@ export class DmChannelListReturnDto { - channelId: number; - partnerName: string; - status: string; - avatar: string; -} \ No newline at end of file + channelId: number; + partnerName: string; + status: string; + avatar: string | null; +} diff --git a/src/common/constants.ts b/src/common/constants.ts index 7133924..6f74d86 100644 --- a/src/common/constants.ts +++ b/src/common/constants.ts @@ -20,3 +20,10 @@ export const CHANNEL_NAME_REGEXP = /^[ㄱ-ㅎㅏ-ㅣ가-힣a-zA-Z0-9]*$/; /* If K is of a lower value, then the rating is changed by a small fraction but if K is of a higher value, then the changes in the rating are significant.*/ export const K = 30; + +export const S3_IMAGE_URL_PREFIX = 'https://d5xph0h5q8hbn.cloudfront.net'; + +export const S3_OBJECT_KEY_PREFIX = 'image'; +export const S3_OBJECT_KEY_SUFFIX = '.jpeg'; + +export const S3_OBJECT_CONTENTTYPE = 'image/jpeg'; diff --git a/src/friends/dto/block-user-return.dto.ts b/src/friends/dto/block-user-return.dto.ts index 991a3ec..87f7382 100644 --- a/src/friends/dto/block-user-return.dto.ts +++ b/src/friends/dto/block-user-return.dto.ts @@ -7,8 +7,7 @@ export class BlockUserReturnDto { @ApiProperty({ description: '닉네임' }) nickname: string; @ApiProperty({ description: '아바타' }) - @IsNotEmpty() - avatar: string; + avatar: string | null; @ApiProperty({ description: '상태(온라인 / 오프라인 / 인게임)' }) status: string; } diff --git a/src/friends/dto/friend-user-return.dto.ts b/src/friends/dto/friend-user-return.dto.ts index 5ef18c2..103fdbe 100644 --- a/src/friends/dto/friend-user-return.dto.ts +++ b/src/friends/dto/friend-user-return.dto.ts @@ -1,6 +1,6 @@ export type FriendUserReturnDto = { id: number; nickname: string; - avatar: string; + avatar: string | null; status: string; }; diff --git a/src/game/dto/emit-event-match-end-param.dto.ts b/src/game/dto/emit-event-match-end-param.dto.ts index 0f9930d..6926eb0 100644 --- a/src/game/dto/emit-event-match-end-param.dto.ts +++ b/src/game/dto/emit-event-match-end-param.dto.ts @@ -3,7 +3,7 @@ import { GameType } from '../../common/enum'; export class EmitEventMatchEndParamDto { gameType: GameType; rivalName: string; - rivalAvatar: string; + rivalAvatar: string | null; rivalScore: number | null; myScore: number | null; isWin: boolean | null; diff --git a/src/game/dto/emit-event-server-game-ready-param.dto.ts b/src/game/dto/emit-event-server-game-ready-param.dto.ts index ccbb332..2ce1024 100644 --- a/src/game/dto/emit-event-server-game-ready-param.dto.ts +++ b/src/game/dto/emit-event-server-game-ready-param.dto.ts @@ -1,6 +1,6 @@ export class EmitEventServerGameReadyParamDto { rivalNickname: string; - rivalAvatar: string; + rivalAvatar: string | null; myPosition: string; ball: { x: number; diff --git a/src/user-repository/dto/my-profile-response.dto.ts b/src/user-repository/dto/my-profile-response.dto.ts index 8cd7950..7f7ad00 100644 --- a/src/user-repository/dto/my-profile-response.dto.ts +++ b/src/user-repository/dto/my-profile-response.dto.ts @@ -1,7 +1,7 @@ export type MyProfileResponseDto = { id: number; nickname: string; - avatar: string; + avatar: string | null; statusMessage: string | null; loseCount: number; winCount: number; diff --git a/src/user-repository/dto/user-profile-return.dto.ts b/src/user-repository/dto/user-profile-return.dto.ts index 69eb62d..9017a8f 100644 --- a/src/user-repository/dto/user-profile-return.dto.ts +++ b/src/user-repository/dto/user-profile-return.dto.ts @@ -1,7 +1,7 @@ export type UserProfileReturnDto = { id: number; nickname: string; - avatar: string; + avatar: string | null; statusMessage: string | null; loseCount: number; winCount: number; diff --git a/src/user-repository/entities/user.entity.ts b/src/user-repository/entities/user.entity.ts index 0a5602b..7d50b37 100644 --- a/src/user-repository/entities/user.entity.ts +++ b/src/user-repository/entities/user.entity.ts @@ -22,9 +22,9 @@ export class User extends BaseEntity { @Matches(NICKNAME_REGEXP) nickname: string; - @Column({ default: null }) + @Column({ default: null, type: 'varchar' }) @IsString() - avatar: string; + avatar: string | null; @Column() @IsNotEmpty() diff --git a/src/user-repository/users.repository.ts b/src/user-repository/users.repository.ts index b9cb8c8..52016c6 100644 --- a/src/user-repository/users.repository.ts +++ b/src/user-repository/users.repository.ts @@ -1,5 +1,9 @@ import { InjectRedis } from '@liaoliaots/nestjs-redis'; -import { BadRequestException, ForbiddenException } from '@nestjs/common'; +import { + BadRequestException, + ForbiddenException, + Inject, +} from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; import Redis from 'ioredis'; import { UserStatus } from 'src/common/enum'; @@ -8,11 +12,23 @@ import { MyProfileResponseDto } from './dto/my-profile-response.dto'; import { UserProfileReturnDto } from './dto/user-profile-return.dto'; import { User } from './entities/user.entity'; import { RankUserReturnDto } from '../users/dto/rank-user-return.dto'; +import s3Config from '../config/s3.config'; +import { ConfigType } from '@nestjs/config'; +import { PutObjectCommand } from '@aws-sdk/client-s3'; +import { getSignedUrl } from '@aws-sdk/s3-request-presigner'; +import { + S3_OBJECT_CONTENTTYPE, + S3_OBJECT_KEY_PREFIX, + S3_OBJECT_KEY_SUFFIX, + S3_IMAGE_URL_PREFIX, +} from '../common/constants'; export class UsersRepository extends Repository { constructor( @InjectRepository(User) private dataSource: DataSource, @InjectRedis() private readonly redis: Redis, + @Inject(s3Config.KEY) + private readonly s3Configure: ConfigType, ) { super(User, dataSource.manager); } @@ -161,4 +177,48 @@ export class UsersRepository extends Repository { return { rankUsers, totalItemCount }; } + + async getAvatarAndPresignedUrl(nickname: string) { + const date = this.getNowDate(); + const key = `${S3_OBJECT_KEY_PREFIX}/${nickname}${date}${S3_OBJECT_KEY_SUFFIX}`; + const preSignedUrl = await this.getPresignedUrl(key); + return { + avatar: `${S3_IMAGE_URL_PREFIX}/${key}`, + preSignedUrl: preSignedUrl, + }; + } + + private async getPresignedUrl(key: string) { + const command = new PutObjectCommand({ + Bucket: this.s3Configure.S3_BUCKET_NAME, + Key: key, + ContentType: S3_OBJECT_CONTENTTYPE, + }); + return await getSignedUrl(this.s3Configure.S3Object, command, { + expiresIn: 180, //초 단위 + }); + } + + // async deleteS3Image(userId: number) { + // const command = new DeleteObjectCommand({ + // Bucket: this.s3Configure.S3_BUCKET_NAME, + // Key: `images/${userId}.jpeg`, + // }); + // + // const response = await this.s3Configure.S3Object.send(command); + // // TODO: s3 이미지 삭제에 실패했을 때? + // if (response.$metadata.httpStatusCode !== 200) { + // console.error(response.$metadata.httpStatusCode); + // // throw new InternalServerErrorException(); + // } + // } + + private getNowDate(): string { + const date = new Date(); + const year = date.getFullYear().toString(); + const month = (date.getMonth() + 1).toString().padStart(2, '0'); // 월은 0부터 시작하므로 +1을 해줌 + const day = date.getDate().toString().padStart(2, '0'); + + return `${year}${month}${day}`; + } } diff --git a/src/users/dto/rank-user-return.dto.ts b/src/users/dto/rank-user-return.dto.ts index f26676a..97d420a 100644 --- a/src/users/dto/rank-user-return.dto.ts +++ b/src/users/dto/rank-user-return.dto.ts @@ -1,6 +1,6 @@ export type RankUserReturnDto = { nickname: string; - avatar: string; + avatar: string | null; ladderScore: number; ranking: number; }; diff --git a/src/users/dto/user-profile-response.dto.ts b/src/users/dto/user-profile-response.dto.ts index e990034..764089a 100644 --- a/src/users/dto/user-profile-response.dto.ts +++ b/src/users/dto/user-profile-response.dto.ts @@ -1,7 +1,7 @@ export type UserProfileResponseDto = { id: number; nickname: string; - avatar: string; + avatar: string | null; statusMessage: string | null; loseCount: number; winCount: number; diff --git a/src/users/ranks.service.ts b/src/users/ranks.service.ts index bdb7d32..6b9da30 100644 --- a/src/users/ranks.service.ts +++ b/src/users/ranks.service.ts @@ -15,15 +15,11 @@ export class RanksService { @InjectRedis() private readonly redis: Redis, ) {} - async findRanksWithPage(page: number): Promise { + async findRanksWithPage(): Promise { //userIDRanking: [userId, userId, userId, ...] // 시간 재기 const startTime = new Date().getTime(); - const userRanking = await this.redis.zrevrange( - 'rankings', - (page - 1) * 15, - page * 15 - 1, - ); + const userRanking = await this.redis.zrevrange('rankings', 0, 99); const endTime = new Date().getTime(); console.log(`redis time: ${endTime - startTime}ms`); @@ -34,7 +30,7 @@ export class RanksService { const rankUsers: RankUserReturnDto[] = foundUsers.map( (user, index) => ({ ...user, - ranking: index + 1 + (page - 1) * 15, + ranking: index + 1, }), ); const totalItemCount = userRanking.length; diff --git a/src/users/users.controller.ts b/src/users/users.controller.ts index a994cc9..6ea79c1 100644 --- a/src/users/users.controller.ts +++ b/src/users/users.controller.ts @@ -2,13 +2,11 @@ import { BadRequestException, Body, Controller, - Delete, Get, Logger, Param, ParseIntPipe, Patch, - Post, Query, UseGuards, } from '@nestjs/common'; @@ -88,9 +86,9 @@ export class UsersController { summary: '랭킹 조회', description: '레디스로부터 pagination해 랭킹 목록을 제공합니다.', }) - async paging(@Query('page', ParseIntPipe, PositiveIntPipe) page: number) { + async paging() { // const rankResponseDto = await this.usersService.findRanksWithPage(); // 레디스 없이 DB에서 랭킹을 조회하는 코드 - let rankResponseDto = await this.ranksServices.findRanksWithPage(page); // 레디스로부터 랭킹을 조회하는 코드 + let rankResponseDto = await this.ranksServices.findRanksWithPage(); // 레디스로부터 랭킹을 조회하는 코드 if (rankResponseDto.rankUsers.length === 0) { this.logger.log('랭킹이 없습니다. 랭킹을 추가합니다.'); rankResponseDto = await this.usersService.findRanksWithPage(); @@ -136,28 +134,12 @@ export class UsersController { }) async updateMyAvatar( @GetUser() user: User, - @Body('avatar') avatar: string, + @Body('avatar') avatar: boolean, ) { - await this.usersService.updateMyAvatar(user.id, avatar); - } - - @UseGuards(AuthGuard('access')) - @Get('/s3image') - async getPresignedUrl(@GetUser() user: User) { - const presignedUrl = await this.usersService.getPresignedUrl(user.id); - - return presignedUrl; - } - - @UseGuards(AuthGuard('access')) - @Delete('/s3image') - async deleteAndGetPresignedUrl(@GetUser() user: User) { - const userId = user.id; - - await this.usersService.deleteS3Image(userId); - - const presignedUrl = await this.usersService.getPresignedUrl(userId); - - return presignedUrl; + return await this.usersService.updateMyAvatar( + user.id, + user.nickname, + avatar, + ); } } diff --git a/src/users/users.service.ts b/src/users/users.service.ts index 77dafe9..44f3c0e 100644 --- a/src/users/users.service.ts +++ b/src/users/users.service.ts @@ -1,10 +1,4 @@ -import { - BadRequestException, - Inject, - Injectable, - InternalServerErrorException, - Logger, -} from '@nestjs/common'; +import { BadRequestException, Injectable, Logger } from '@nestjs/common'; import * as bcrypt from 'bcrypt'; import { DBUpdateFailureException } from '../common/exception/custom-exception'; import { GameRepository } from '../game/game.repository'; @@ -12,35 +6,21 @@ import { BlocksRepository } from '../friends/blocks.repository'; import { UserProfileResponseDto } from './dto/user-profile-response.dto'; import { FriendsRepository } from '../friends/friends.repository'; import { UsersRepository } from '../user-repository/users.repository'; -import s3Config from '../config/s3.config'; -import { ConfigType } from '@nestjs/config'; -import { - DeleteObjectCommand, - PutObjectCommand, - S3Client, -} from '@aws-sdk/client-s3'; -import { getSignedUrl } from '@aws-sdk/s3-request-presigner'; @Injectable() export class UsersService { - private readonly s3: S3Client; - constructor( - private readonly userRepository: UsersRepository, + private readonly usersRepository: UsersRepository, private readonly gameRepository: GameRepository, private readonly friendsRepository: FriendsRepository, private readonly blocksRepository: BlocksRepository, - @Inject(s3Config.KEY) - private readonly s3Configure: ConfigType, - ) { - this.s3 = this.s3Configure.S3Object; - } + ) {} private readonly logger = new Logger(UsersService.name); async findGameHistoriesWithPage(nickname: string, page: number) { // 유저 id 조회 - const targetUser = await this.userRepository.findUserByNickname( + const targetUser = await this.usersRepository.findUserByNickname( nickname, ); if (!targetUser) { @@ -68,7 +48,7 @@ export class UsersService { } async findMyProfile(userId: number) { - const myProfile = await this.userRepository.findMyProfile(userId); + const myProfile = await this.usersRepository.findMyProfile(userId); return myProfile; } @@ -77,9 +57,10 @@ export class UsersService { userId: number, targetUserNickname: string, ): Promise { - const userProfile = await this.userRepository.findUserProfileByNickname( - targetUserNickname, - ); + const userProfile = + await this.usersRepository.findUserProfileByNickname( + targetUserNickname, + ); const friend = await this.friendsRepository.findFriend( userId, @@ -99,7 +80,7 @@ export class UsersService { } async updateMyStatusMessage(userId: number, statusMessage: string | null) { - const updateRes = await this.userRepository.update(userId, { + const updateRes = await this.usersRepository.update(userId, { statusMessage: statusMessage, }); @@ -108,18 +89,38 @@ export class UsersService { } } - async updateMyAvatar(userId: number, avatar: string) { - const updateRes = await this.userRepository.update(userId, { - avatar: avatar, + async updateMyAvatar(userId: number, nickname: string, hasAvatar: boolean) { + /* + TODO: 업데이트한지 3일 이내면 에러 던지기, + 현 db 상태와 같다면(avatar가 이미 null인데 hasAvatar = false 라면) update 진행 중지 + */ + let ret; + let updateUserDataDto; + if (hasAvatar) { + const { avatar, preSignedUrl } = + await this.usersRepository.getAvatarAndPresignedUrl(nickname); + updateUserDataDto = { + avatar: avatar, + }; + ret = preSignedUrl; + } else { + updateUserDataDto = { + avatar: null, + }; + ret = null; + } + const updateRes = await this.usersRepository.update(userId, { + ...updateUserDataDto, }); if (updateRes.affected !== 1) { throw DBUpdateFailureException(`user ${userId} update failed`); } + return ret; } async getUserIfRefreshTokenMatches(refreshToken: string, userId: number) { - const user = await this.userRepository.findOne({ + const user = await this.usersRepository.findOne({ where: { id: userId }, }); @@ -140,31 +141,6 @@ export class UsersService { } async findRanksWithPage() { - return await this.userRepository.findRanksWithPage(); - } - - async getPresignedUrl(userId: number) { - // TODO: 수정 72시간 이내에는 에러 - - const command = new PutObjectCommand({ - Bucket: this.s3Configure.S3_BUCKET_NAME, - Key: `images/${userId}.jpeg`, - ContentType: 'image/jpeg', - }); - return await getSignedUrl(this.s3, command, { expiresIn: 3000 }); - } - - async deleteS3Image(userId: number) { - const command = new DeleteObjectCommand({ - Bucket: this.s3Configure.S3_BUCKET_NAME, - Key: `images/${userId}.jpeg`, - }); - - const response = await this.s3.send(command); - // TODO: s3 이미지 삭제에 실패했을 때? - if (response.$metadata.httpStatusCode !== 200) { - console.error(response.$metadata.httpStatusCode); - // throw new InternalServerErrorException(); - } + return await this.usersRepository.findRanksWithPage(); } } From 4f427381fc7e186a47a403b44e1ed1093fcdc648 Mon Sep 17 00:00:00 2001 From: jiyun Date: Wed, 24 Apr 2024 23:32:53 +0900 Subject: [PATCH 2/2] =?UTF-8?q?fix:=20s3=20=EC=97=85=EB=A1=9C=EB=93=9C?= =?UTF-8?q?=EC=8B=9C=20=EB=B0=98=ED=99=98=EA=B0=92=EC=9D=84=20preSignedUrl?= =?UTF-8?q?=EB=A1=9C=20=EB=AA=85=EC=8B=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/auth/auth.controller.ts | 8 +++++++- src/users/users.controller.ts | 4 +++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/auth/auth.controller.ts b/src/auth/auth.controller.ts index 437415c..450bc9a 100644 --- a/src/auth/auth.controller.ts +++ b/src/auth/auth.controller.ts @@ -111,7 +111,13 @@ export class AuthController { const nickname = signupRequestDto.nickname; const avatar = signupRequestDto.avatar; - return await this.authService.signup(user.id, nickname, avatar); + const preSignedUrl = await this.authService.signup( + user.id, + nickname, + avatar, + ); + + return { preSignedUrl: preSignedUrl }; } // TODO: 테스트용 코드. 추후 삭제 diff --git a/src/users/users.controller.ts b/src/users/users.controller.ts index 6ea79c1..cc6396b 100644 --- a/src/users/users.controller.ts +++ b/src/users/users.controller.ts @@ -136,10 +136,12 @@ export class UsersController { @GetUser() user: User, @Body('avatar') avatar: boolean, ) { - return await this.usersService.updateMyAvatar( + const preSignedUrl = await this.usersService.updateMyAvatar( user.id, user.nickname, avatar, ); + + return { preSignedUrl: preSignedUrl }; } }